diff --git a/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj b/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj index c77ed03b..a0968e33 100644 --- a/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj +++ b/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj @@ -229,11 +229,11 @@ + + - - @@ -250,18 +250,9 @@ - - - - - - - - - @@ -269,20 +260,13 @@ - - - - - - - diff --git a/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj.filters b/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj.filters index 8e7a9dbf..1d77b2ae 100644 --- a/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.141.GDK.C/Microsoft.Xbox.Services.141.GDK.C.vcxproj.filters @@ -295,15 +295,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -334,21 +334,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -364,21 +352,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -651,10 +630,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -693,18 +672,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -714,9 +681,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -726,30 +690,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - diff --git a/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj b/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj index 6f47090d..6da46426 100644 --- a/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj +++ b/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj @@ -229,11 +229,11 @@ + + - - @@ -250,18 +250,9 @@ - - - - - - - - - @@ -269,20 +260,13 @@ - - - - - - - diff --git a/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj.filters b/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj.filters index 8e7a9dbf..1d77b2ae 100644 --- a/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.142.GDK.C/Microsoft.Xbox.Services.142.GDK.C.vcxproj.filters @@ -295,15 +295,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -334,21 +334,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -364,21 +352,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -651,10 +630,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -693,18 +672,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -714,9 +681,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -726,30 +690,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - diff --git a/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj b/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj index b8f179a5..e53bfb08 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj +++ b/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj @@ -236,11 +236,11 @@ + + - - @@ -257,19 +257,9 @@ - - - - - - - - - - @@ -277,22 +267,15 @@ - - - - - - - @@ -340,7 +323,6 @@ - diff --git a/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj.filters b/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj.filters index 1cb600d1..c5ce0493 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.UnitTest.141.TAEF/Microsoft.Xbox.Services.UnitTest.141.TAEF.vcxproj.filters @@ -286,15 +286,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -325,24 +325,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -358,21 +343,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -484,9 +460,6 @@ C++ Source\UnitTests\Tests - - C++ Source\UnitTests\Tests - C++ Source\UnitTests\Tests @@ -756,10 +729,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -798,18 +771,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -819,9 +780,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -831,30 +789,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - C++ Source\UnitTests\Mocks diff --git a/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj b/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj index 09618be1..4244653e 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj +++ b/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj @@ -273,11 +273,11 @@ + + - - @@ -294,19 +294,9 @@ - - - - - - - - - - @@ -314,22 +304,15 @@ - - - - - - - @@ -377,7 +360,6 @@ - diff --git a/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj.filters b/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj.filters index 7b927cce..3691894e 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.UnitTest.141.TE/Microsoft.Xbox.Services.UnitTest.141.TE.vcxproj.filters @@ -286,15 +286,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -325,24 +325,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -358,21 +343,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -484,9 +460,6 @@ C++ Source\UnitTests\Tests - - C++ Source\UnitTests\Tests - C++ Source\UnitTests\Tests @@ -756,10 +729,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -798,18 +771,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -819,9 +780,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -831,30 +789,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - C++ Source\UnitTests\Mocks diff --git a/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj b/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj index 5e2f86ac..8063a73b 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj +++ b/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj @@ -236,11 +236,11 @@ + + - - @@ -257,19 +257,9 @@ - - - - - - - - - - @@ -277,22 +267,15 @@ - - - - - - - @@ -340,7 +323,6 @@ - diff --git a/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj.filters b/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj.filters index 1cb600d1..c5ce0493 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.UnitTest.142.TAEF/Microsoft.Xbox.Services.UnitTest.142.TAEF.vcxproj.filters @@ -286,15 +286,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -325,24 +325,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -358,21 +343,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -484,9 +460,6 @@ C++ Source\UnitTests\Tests - - C++ Source\UnitTests\Tests - C++ Source\UnitTests\Tests @@ -756,10 +729,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -798,18 +771,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -819,9 +780,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -831,30 +789,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - C++ Source\UnitTests\Mocks diff --git a/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj b/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj index d43760fd..e427c22b 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj +++ b/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj @@ -273,11 +273,11 @@ + + - - @@ -294,19 +294,9 @@ - - - - - - - - - - @@ -314,22 +304,15 @@ - - - - - - - @@ -377,7 +360,6 @@ - diff --git a/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj.filters b/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj.filters index 7b927cce..3691894e 100644 --- a/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj.filters +++ b/Build/Microsoft.Xbox.Services.UnitTest.142.TE/Microsoft.Xbox.Services.UnitTest.142.TE.vcxproj.filters @@ -286,15 +286,15 @@ C++ Source\Shared + + C++ Source\Shared + C++ Source\Shared C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -325,24 +325,9 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -358,21 +343,12 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System @@ -484,9 +460,6 @@ C++ Source\UnitTests\Tests - - C++ Source\UnitTests\Tests - C++ Source\UnitTests\Tests @@ -756,10 +729,10 @@ C++ Source\Shared - + C++ Source\Shared - + C++ Source\Shared @@ -798,18 +771,6 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared @@ -819,9 +780,6 @@ C++ Source\Shared - - C++ Source\Shared - C++ Source\Shared @@ -831,30 +789,18 @@ C++ Source\Shared - - C++ Source\Shared - - - C++ Source\Shared - C++ Source\Shared C++ Source\Shared - - C++ Source\System - C++ Source\System C++ Source\System - - C++ Source\System - C++ Source\UnitTests\Mocks diff --git a/Custom.props b/Custom.props index 72ecde9c..77f68aac 100644 --- a/Custom.props +++ b/Custom.props @@ -11,9 +11,7 @@ - - 1 - 0 + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Android SDK Tools@Path) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Android SDK Tools@Path) diff --git a/External/Xal/Source/Xal/Include/Xal/xal_types.h b/External/Xal/Source/Xal/Include/Xal/xal_types.h index 8e89e2d6..5c6ee4db 100644 --- a/External/Xal/Source/Xal/Include/Xal/xal_types.h +++ b/External/Xal/Source/Xal/Include/Xal/xal_types.h @@ -63,6 +63,7 @@ extern "C" #define E_XAL_NODEFAULTUSER MAKE_E_HC(0x5111L) // 0x89235111 #define E_XAL_FAILEDTORESOLVE MAKE_E_HC(0x5112L) // 0x89235112 #define E_XAL_NOACCOUNTPROVIDER MAKE_E_HC(0x5113L) // 0x89235113 +#define E_XAL_MISMATCHEDTITLEANDCLIENTIDS MAKE_E_HC(0x5114L) // 0x89235114 // E_XAL_INTERNAL_* values should never be returned to callers of XAL. #define E_XAL_INTERNAL_SWITCHUSER MAKE_E_HC(0x5171L) // 0x89235171 diff --git a/External/rapidjson b/External/rapidjson index d87b698d..a1116a83 160000 --- a/External/rapidjson +++ b/External/rapidjson @@ -1 +1 @@ -Subproject commit d87b698d0fcc10a5f632ecbc80a9cb2a8fa094a5 +Subproject commit a1116a83bda2313d45d73703932ecf145ae997ec diff --git a/Include/cpprestinclude/cpprest/asyncrt_utils.h b/Include/cpprestinclude/cpprest/asyncrt_utils.h index 5069a85c..8e280094 100644 --- a/Include/cpprestinclude/cpprest/asyncrt_utils.h +++ b/Include/cpprestinclude/cpprest/asyncrt_utils.h @@ -594,7 +594,7 @@ public: void set_length(int length) { m_length = length; } private: - static const utility::string_t c_allowed_chars; + static const utility::char_t* c_allowed_chars; std::mt19937 m_random; int m_length; }; diff --git a/Include/cpprestinclude/cpprest/details/asyncrt_utils.hpp b/Include/cpprestinclude/cpprest/details/asyncrt_utils.hpp index 995ca308..13d72282 100644 --- a/Include/cpprestinclude/cpprest/details/asyncrt_utils.hpp +++ b/Include/cpprestinclude/cpprest/details/asyncrt_utils.hpp @@ -44,6 +44,7 @@ #pragma warning( disable : 26444 ) // ignore various unnamed objects #pragma warning( disable : 26498 ) // ignore eof warning #pragma warning( disable : 26812 ) // enum instead of enum class +#pragma warning( disable : 4365 ) #endif // Could use C++ standard library if not __GLIBCXX__, @@ -697,12 +698,12 @@ template uint64_t timeticks_from_second(StringIterator begin, StringIterator end) { int size = (int)(end - begin); - _ASSERTE(begin[0] == U('.')); + _ASSERTE(begin[0] == _T('.')); uint64_t ufrac_second = 0; for (int i = 1; i <= 7; ++i) { ufrac_second *= 10; - int add = i < size ? begin[i] - U('0') : 0; + int add = i < size ? begin[i] - _T('0') : 0; ufrac_second += add; } return ufrac_second; @@ -712,7 +713,7 @@ void extract_fractional_second(const utility::string_t& dateString, utility::str { resultString = dateString; // First, the string must be strictly longer than 2 characters, and the trailing character must be 'Z' - if (resultString.size() > 2 && resultString[resultString.size() - 1] == U('Z')) + if (resultString.size() > 2 && resultString[resultString.size() - 1] == _T('Z')) { // Second, find the last non-digit by scanning the string backwards auto last_non_digit = std::find_if_not(resultString.rbegin() + 1, resultString.rend(), is_digit); @@ -720,7 +721,7 @@ void extract_fractional_second(const utility::string_t& dateString, utility::str { // Finally, make sure the last non-digit is a dot: auto last_dot = last_non_digit.base() - 1; - if (*last_dot == U('.')) + if (*last_dot == _T('.')) { // Got it! Now extract the fractional second auto last_before_Z = std::end(resultString) - 1; @@ -1046,11 +1047,11 @@ utility::seconds __cdecl timespan::xml_duration_to_seconds(const utility::string return utility::seconds(numSecs); } -const utility::string_t nonce_generator::c_allowed_chars(_XPLATSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); +const utility::char_t * nonce_generator::c_allowed_chars = _XPLATSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); utility::string_t nonce_generator::generate() { - std::uniform_int_distribution<> distr(0, static_cast(c_allowed_chars.length() - 1)); + std::uniform_int_distribution<> distr(0, static_cast(ustrlen(c_allowed_chars) - 1)); utility::string_t result; result.reserve(length()); std::generate_n(std::back_inserter(result), length(), [&]() { return c_allowed_chars[distr(m_random)]; } ); diff --git a/Include/cpprestinclude/cpprest/details/base64.hpp b/Include/cpprestinclude/cpprest/details/base64.hpp index 81e4793e..487ed421 100644 --- a/Include/cpprestinclude/cpprest/details/base64.hpp +++ b/Include/cpprestinclude/cpprest/details/base64.hpp @@ -28,6 +28,7 @@ using namespace utility; #if HC_PLATFORM_IS_MICROSOFT #pragma warning( push ) #pragma warning( disable : 28020 ) // ignore expression validation +#pragma warning( disable : 4365 ) #endif std::vector _from_base64(const utility::string_t& str); diff --git a/Include/cpprestinclude/cpprest/details/basic_types.h b/Include/cpprestinclude/cpprest/details/basic_types.h index 996b866f..f6bf724d 100644 --- a/Include/cpprestinclude/cpprest/details/basic_types.h +++ b/Include/cpprestinclude/cpprest/details/basic_types.h @@ -56,6 +56,7 @@ typedef std::wstringstream stringstream_t; #define ucout std::wcout #define ucin std::wcin #define ucerr std::wcerr +#define ustrlen wcslen #else // // On POSIX platforms, all strings are narrow @@ -73,6 +74,7 @@ typedef std::stringstream stringstream_t; #define ucout std::cout #define ucin std::cin #define ucerr std::cerr +#define ustrlen strlen #endif // endif _UTF16_STRINGS #ifndef _TURN_OFF_PLATFORM_STRING diff --git a/Include/cpprestinclude/cpprest/details/json_parsing.hpp b/Include/cpprestinclude/cpprest/details/json_parsing.hpp index ef37e29b..7742dda0 100644 --- a/Include/cpprestinclude/cpprest/details/json_parsing.hpp +++ b/Include/cpprestinclude/cpprest/details/json_parsing.hpp @@ -18,7 +18,10 @@ #if defined(_MSC_VER) #pragma warning(disable : 4127) // allow expressions like while(true) pass +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4061 ) #endif + using namespace web; using namespace web::json; using namespace utility::conversions; diff --git a/Include/cpprestinclude/cpprest/details/json_serialization.hpp b/Include/cpprestinclude/cpprest/details/json_serialization.hpp index 1c875b6d..4e0836d2 100644 --- a/Include/cpprestinclude/cpprest/details/json_serialization.hpp +++ b/Include/cpprestinclude/cpprest/details/json_serialization.hpp @@ -25,6 +25,11 @@ using namespace web; using namespace web::json; using namespace utility::conversions; +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#endif + // // JSON Serialization // @@ -261,3 +266,7 @@ utility::string_t json::value::serialize() const #endif return m_value->to_string(); } + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif diff --git a/Include/cpprestinclude/cpprest/details/uri.hpp b/Include/cpprestinclude/cpprest/details/uri.hpp index d76d512e..b72b59a5 100644 --- a/Include/cpprestinclude/cpprest/details/uri.hpp +++ b/Include/cpprestinclude/cpprest/details/uri.hpp @@ -31,6 +31,7 @@ using namespace utility::conversions; #pragma warning( push ) #pragma warning( disable : 26444 ) // ignore various unnamed objects #pragma warning( disable : 26812 ) // enum instead of enum class +#pragma warning( disable : 4365 ) #endif namespace web { namespace details diff --git a/Include/xsapi-c/achievements_c.h b/Include/xsapi-c/achievements_c.h index e84876b9..f7310600 100644 --- a/Include/xsapi-c/achievements_c.h +++ b/Include/xsapi-c/achievements_c.h @@ -376,7 +376,7 @@ typedef struct XblAchievement _Field_z_ const char* id; /// - /// The UTF-8 encoded ID of the service configuration set associated with the achievement. + /// The Service Configuration ID (SCID) that is associated with the achievement. The SCID is considered case sensitive so paste it directly from the Partner Center /// _Field_z_ const char* serviceConfigurationId; @@ -467,7 +467,7 @@ typedef struct XblAchievement XblAchievementReward* rewards; /// - /// The size of **rewards**>. + /// The size of **rewards**. /// size_t rewardsCount; @@ -535,12 +535,12 @@ typedef struct XblAchievementUnlockEvent _Field_z_ const char* deepLink; /// - /// The ratio of the count of users who have unlocked the achievement / the total number unique users of that title expressed as a float value >= 0.0 and <= 100.0 rounded to 2 decimal places. + /// The ratio of the count of users who have unlocked the achievement / the total number unique users of that title expressed as a fractional value >= 0.0 and <= 1.0 rounded to 2 decimal places. /// float rarityPercentage; /// - /// "Rare" or "Common" - where Rare achievements are those with a rarityPercentage < 10% and "Common" is everything else. (This string is not localized). + /// "Rare" or "Common" - where Rare achievements are those with a rarityPercentage <= 9% (or 0.9) and "Common" is everything else. (This string is not localized). /// XblAchievementRarityCategory rarityCategory; @@ -557,7 +557,7 @@ typedef struct XblAchievementUnlockEvent /// /// /// This handle is used by other APIs to get the achievement objects and to get the -/// next page of achievements from the service if there is is one. +/// next page of achievements from the service if there is one. /// The handle must be closed using /// when the result is no longer needed. /// @@ -594,7 +594,7 @@ STDAPI XblAchievementsResultGetAchievements( /// Checks if there are more pages of achievements to retrieve from the service. /// /// Achievement result handle. -/// Passes back True if there are more results to retrieve, false otherwise. +/// Passes back true if there are more results to retrieve, false otherwise. /// HRESULT return code for this API operation. STDAPI XblAchievementsResultHasNext( _In_ XblAchievementsResultHandle resultHandle, @@ -716,7 +716,7 @@ STDAPI XblAchievementsUpdateAchievementAsync( /// An xbox live context handle created with XblContextCreateHandle. /// The Xbox User ID of the player. /// The title ID. -/// The UTF-8 encoded service configuration ID (SCID) for the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The UTF-8 encoded achievement ID as defined by XDP or Dev Center. /// The completion percentage of the achievement to indicate progress. /// Valid values are from 1 to 100. Set to 100 to unlock the achievement. @@ -746,7 +746,7 @@ STDAPI XblAchievementsUpdateAchievementForTitleIdAsync( /// /// An xbox live context handle created with XblContextCreateHandle. /// The Xbox User ID of the player. -/// The UTF-8 encoded service configuration ID (SCID) for the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The UTF-8 encoded unique identifier of the Achievement as defined by XDP or Dev Center. /// Caller allocated AsyncBlock. /// HRESULT return code for this API operation. @@ -769,7 +769,7 @@ STDAPI XblAchievementsGetAchievementAsync( /// The same AsyncBlock that passed to XblAchievementsGetAchievementAsync. /// The achievement result handle. /// This handle is used by other APIs to get the achievement objects -/// and to get the next page of achievements from the service if there is is one. +/// and to get the next page of achievements from the service if there is one. /// The handle must be closed using when the result is no longer needed. /// /// HRESULT return code for this API operation. diff --git a/Include/xsapi-c/achievements_manager_c.h b/Include/xsapi-c/achievements_manager_c.h index 3b43b08c..197f7a6b 100644 --- a/Include/xsapi-c/achievements_manager_c.h +++ b/Include/xsapi-c/achievements_manager_c.h @@ -217,8 +217,8 @@ STDAPI XblAchievementsManagerGetAchievement( /// the result is no longer needed. /// /// -/// Passing in for sortField yields the same results -/// as passing in since all achievements tracked +/// Passing in XblAchievementOrderBy::TitleId for sortField yields the same results +/// as passing in XblAchievementOrderBy::DefaultOrder since all achievements tracked /// by achievement manager will have the same TitleId. /// /// HRESULT return code for this API operation. diff --git a/Include/xsapi-c/matchmaking_c.h b/Include/xsapi-c/matchmaking_c.h index c4bfc2a4..7ddd17cd 100644 --- a/Include/xsapi-c/matchmaking_c.h +++ b/Include/xsapi-c/matchmaking_c.h @@ -191,7 +191,7 @@ STDAPI XblMatchmakingCreateMatchTicketResult( /// Deletes a the match ticket on the server. /// /// Xbox live context for the local user. -/// The service config id that is specific for the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The name of the hopper where the match ticket is located. /// The id of the ticket to delete on the server. /// The AsyncBlock for this operation. @@ -209,7 +209,7 @@ STDAPI XblMatchmakingDeleteMatchTicketAsync( /// Retrieves the properties of a match ticket from the server. /// /// Xbox live context for the local user. -/// The service config id that is specific for the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The name of the hopper where the match ticket is located. /// The ticket id of the match ticket to retrieve. /// The AsyncBlock for this operation. @@ -257,7 +257,7 @@ STDAPI XblMatchmakingGetMatchTicketDetailsResult( /// Gets statistics about a hopper such as how many players are in it. /// /// Xbox live context for the local user. -/// The service config id that is specific for the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The name of the hopper to query stats for. /// The AsyncBlock for this operation. /// HRESULT return code for this API operation. diff --git a/Include/xsapi-c/multiplayer_c.h b/Include/xsapi-c/multiplayer_c.h index f03cf38d..a298a615 100644 --- a/Include/xsapi-c/multiplayer_c.h +++ b/Include/xsapi-c/multiplayer_c.h @@ -518,7 +518,7 @@ enum class XblMultiplayerSessionMemberStatus : uint32_t /// /// The member is inactive in the current title. /// The member may be active in another title as specified by ActiveTitleId. - /// If a inactive member doesn't mark themselves as Active within the MemberInactiveTimeout they will be removed from the session. + /// If an inactive member doesn't mark themselves as Active within the MemberInactiveTimeout they will be removed from the session. /// Inactive, @@ -966,7 +966,7 @@ typedef struct XblMultiplayerSessionConstants uint64_t MemberReservedTimeout; /// - /// If a inactive member reservation does not become active within this timeout, then inactive member is removed from the session. + /// If an inactive member reservation does not become active within this timeout, then the inactive member is removed from the session. /// uint64_t MemberInactiveTimeout; @@ -1110,7 +1110,7 @@ typedef struct XblMultiplayerSessionReferenceUri /// /// Creates an XblMultiplayerSessionReference from a scid, session template name, and session name. /// -/// The service configuration id that the session is a part of. +/// The Service Configuration ID (SCID) that the session is a part of. The SCID is considered case sensitive so paste it directly from the Partner Center /// The session template name. /// The session name. /// A reference to the multiplayer session that was created. @@ -1792,7 +1792,7 @@ typedef struct XblMultiplayerSessionInfo time_t StartTime; /// - /// If any timeouts are in progress, this is the date when the the next timer will fire. + /// If any timeouts are in progress, this is the date when the next timer will fire. /// time_t NextTimer; @@ -2002,13 +2002,14 @@ typedef struct XblMultiplayerSessionStringAttribute } XblMultiplayerSessionStringAttribute; /// -/// An associative attribute that can be attached to a multiplayer session search handle when it is created. +/// An associative attribute that can be attached to a multiplayer session search handle when it is created. /// Attribute names be lower-case alphanumeric, and start with a letter. /// typedef struct XblMultiplayerSessionNumberAttribute { /// /// Name of the attribute. + /// Attribute names be lower-case alphanumeric, and start with a letter. /// char name[XBL_MULTIPLAYER_SEARCH_HANDLE_MAX_FIELD_LENGTH]; @@ -2141,7 +2142,7 @@ STDAPI_(XblMultiplayerSessionChangeTypes) XblMultiplayerSessionSubscribedChangeT ) XBL_NOEXCEPT; /// -/// Host candidates are a ordered list of device tokens, ordered by preference as specified by XblMultiplayerMetrics +/// Host candidates are an ordered list of device tokens, ordered by preference as specified by XblMultiplayerMetrics /// in the session constants. /// /// Handle to the multiplayer session. @@ -2784,7 +2785,7 @@ STDAPI XblMultiplayerSessionLeave( /// Indicates the current user status. /// HRESULT return code for this API operation. /// -/// You cannot set the the user to reserved or ready in this manner. +/// You cannot set the user to reserved or ready in this manner. /// Use to add a member reservation. /// STDAPI XblMultiplayerSessionCurrentUserSetStatus( @@ -2838,7 +2839,7 @@ typedef struct XblFormattedSecureDeviceAddress /// STDAPI XblFormatSecureDeviceAddress( _In_ const char* deviceId, - _Out_ XblFormattedSecureDeviceAddress* address + _Inout_ XblFormattedSecureDeviceAddress* address ) XBL_NOEXCEPT; #endif @@ -3194,8 +3195,10 @@ STDAPI XblMultiplayerSearchHandleGetCustomSessionPropertiesJson( /// The AsyncBlock for this operation. /// HRESULT return code for this API operation. /// -/// Call XblMultiplayerWriteSessionResult() to get the result. -/// Call XblMultiplayerSessionWriteStatus() to get the write status. +/// In the async callback, call XblMultiplayerWriteSessionResult() to get a XblMultiplayerSessionHandle handle. +/// Use that handle to call XblMultiplayerSessionWriteStatus() to get the write status. +/// The call to XblMultiplayerWriteSessionAsync() will only fail if the args passed to it are invalid or in very rare +/// cases where it could not start the async task. /// /// Calls V105 PUT /serviceconfigs/{serviceConfigurationId}/sessionTemplates/{sessiontemplateName}/sessions/{sessionName} STDAPI XblMultiplayerWriteSessionAsync( @@ -3209,14 +3212,21 @@ STDAPI XblMultiplayerWriteSessionAsync( /// Gets the result of a XblMultiplayerWriteSessionAsync operation. /// /// The AsyncBlock for this operation. -/// Passes back a handle to a new instance of a local multiplayer session object. -/// It must be release by the caller with . +/// Passes back a handle to a new instance of a local multiplayer session object. +/// The XblMultiplayerSessionHandle must be released by the caller by calling . +/// Use XblMultiplayerSession* APIs to get session data from the handle. /// If the updated session object is not needed, passing nullptr will cause the new multiplayer -/// session object to be cleaned up immediately. -/// HRESULT return code for this API operation. +/// session object to be cleaned up immediately. +/// +/// HRESULT return code for this API operation. +/// It will be a failure HRESULT if there was a network error or failure HTTP status code unless its a 412 (Precondition Failed). +/// A 412 returns success since the service also returns latest session state, so you must call XblMultiplayerSessionWriteStatus() to get the +/// write status and call XblMultiplayerSession* APIs to get session data from the handle. +/// /// -/// Note that if you leave a session that you are the the last member of and the sessionEmptyTimeout +/// Note that if you leave a session that you are the last member of and the sessionEmptyTimeout /// is equal to 0, then the session will be deleted immediately. +/// Call XblMultiplayerSessionWriteStatus() to get the write status. /// STDAPI XblMultiplayerWriteSessionResult( _Inout_ XAsyncBlock* async, @@ -3257,7 +3267,7 @@ STDAPI XblMultiplayerWriteSessionByHandleAsync( /// If the updated session object is not needed, passing nullptr will cause the new multiplayer session object to be cleaned up immediately. /// HRESULT return code for this API operation. /// -/// Note that if you leave a session that you are the the last member of and the sessionEmptyTimeout +/// Note that if you leave a session that you are the last member of and the sessionEmptyTimeout /// is equal to 0, then the session will be deleted immediately and a nullptr will be returned. /// STDAPI XblMultiplayerWriteSessionByHandleResult( @@ -3379,7 +3389,7 @@ STDAPI XblMultiplayerSetActivityAsync( /// Clears the user's current activity session for the specified serviceConfigurationId. /// /// Xbox live context for the local user. -/// A string containing the serviceConfigurationId in which to clear activity. +/// The Service Configuration ID (SCID) in which to clear activity. The SCID is considered case sensitive so paste it directly from the Partner Center /// The AsyncBlock for this operation. /// HRESULT return code for this API operation. STDAPI XblMultiplayerClearActivityAsync( @@ -3483,7 +3493,7 @@ STDAPI XblMultiplayerDeleteSearchHandleAsync( /// Search for sessions by their associated search handles. /// /// Xbox live context for the local user. -/// The scid within which to query for search handles. +/// The Service Configuration ID (SCID) within which to query for search handles. The SCID is considered case sensitive so paste it directly from the Partner Center /// The name of the template to query for search handles. /// This specifies the attribute to sort the search handles by. Pass empty string to default to ordering by 'Timestamp asc'. /// Pass true to order ascending, false to order descending. @@ -3595,7 +3605,7 @@ STDAPI XblMultiplayerSendInvitesAsync( /// /// The AsyncBlock for this operation. /// The number of handles in the handles array. Size should be equal to the number of invites requested. -/// A caller allocated array to pass back the invite handle results +/// A caller allocated array to pass back the invite handle results. /// The handle ID strings corresponding to the invites that have been sent. /// HRESULT return code for this API operation. STDAPI XblMultiplayerSendInvitesResult( @@ -3609,7 +3619,7 @@ STDAPI XblMultiplayerSendInvitesResult( /// Queries for the current activity for a socialgroup of users associated with a particular "owner" user. /// /// Xbox live context for the local user. -/// The scid within which to query for activities. +/// The Service Configuration ID (SCID) within which to query for activities. The SCID is considered case sensitive so paste it directly from the Partner Center /// The person whose social group will be used for the query. /// The social group to use in order to get the list of users. (e.g. "people" or "favorites") /// The AsyncBlock for this operation. @@ -3629,7 +3639,7 @@ STDAPI XblMultiplayerGetActivitiesForSocialGroupAsync( /// Queries for the current activity for a socialgroup of users associated with a particular "owner" user. /// /// Xbox live context for the local user. -/// The scid within which to query for activities. +/// The Service Configuration ID (SCID) within which to query for activities. The SCID is considered case sensitive so paste it directly from the Partner Center /// The person whose social group will be used for the query. /// The social group to use in order to get the list of users. (e.g. "people" or "favorites") /// The AsyncBlock for this operation. @@ -3705,7 +3715,7 @@ STDAPI XblMultiplayerGetActivitiesWithPropertiesForSocialGroupResult( /// Queries for the current activity for a set of users specified by xuid. /// /// Xbox live context for the local user. -/// The scid within which to query for activities. +/// The Service Configuration ID (SCID) within which to query for activities. The SCID is considered case sensitive so paste it directly from the Partner Center /// The list of user ids to find activities for. /// The size of the xuids array. /// The AsyncBlock for this operation. @@ -3725,7 +3735,7 @@ STDAPI XblMultiplayerGetActivitiesForUsersAsync( /// Queries for the current activity for a set of users specified by xuid. /// /// Xbox live context for the local user. -/// The scid within which to query for activities. +/// The Service Configuration ID (SCID) within which to query for activities. The SCID is considered case sensitive so paste it directly from the Partner Center /// The list of user ids to find activities for. /// The size of the xuids array. /// The AsyncBlock for this operation. @@ -3838,7 +3848,7 @@ typedef void CALLBACK XblMultiplayerSessionChangedHandler( /// /// Registers an event handler for notifications when a multiplayer session changes. If the RTA subscription has not -/// been explicitly enabled with , adding session changed handlers will +/// been explicitly enabled with , adding session changed handlers will /// enable it automatically. Use the returned XblFunctionContext to unregister the handler. /// /// Xbox live context for the local user. diff --git a/Include/xsapi-c/multiplayer_manager_c.h b/Include/xsapi-c/multiplayer_manager_c.h index dc9d5ecc..80621dd2 100644 --- a/Include/xsapi-c/multiplayer_manager_c.h +++ b/Include/xsapi-c/multiplayer_manager_c.h @@ -977,7 +977,7 @@ STDAPI_(const char*) XblMultiplayerManagerGameSessionCorrelationId() XBL_NOEXCEP /// Object containing identifying information for the session. /// Returns null if a game session has not yet been established. /// -/// A pointer to the the multiplayer session reference. +/// A pointer to the multiplayer session reference. /// The memory for the returned string pointer remains valid until the next call to XblMultiplayerManagerDoWork. STDAPI_(const XblMultiplayerSessionReference*) XblMultiplayerManagerGameSessionSessionReference() XBL_NOEXCEPT; diff --git a/Include/xsapi-c/presence_c.h b/Include/xsapi-c/presence_c.h index 8ee93bee..0c835d2b 100644 --- a/Include/xsapi-c/presence_c.h +++ b/Include/xsapi-c/presence_c.h @@ -663,7 +663,7 @@ STDAPI_XBL_DEPRECATED XblPresenceUnsubscribeFromDevicePresenceChange( /// /// Subscribes to title presence change notifications. /// DEPRECATED. This API will be removed in a future release. Individual RTA subscription will be managed automatically by XSAPI as -/// titles are tracked with . +/// titles are tracked with . /// /// Xbox live context for the local user. /// The Xbox User ID of the person of the subscription. @@ -750,7 +750,7 @@ typedef void CALLBACK XblPresenceTitlePresenceChangedHandler( /// /// Registers an event handler for title presence change notifications. Notifications will -/// only be received for the Users and Titles configured with and +/// only be received for the Users and Titles configured with and /// respectively. /// /// Xbox live context for the local user. diff --git a/Include/xsapi-c/social_c.h b/Include/xsapi-c/social_c.h index 0f5198e8..a00d8ce0 100644 --- a/Include/xsapi-c/social_c.h +++ b/Include/xsapi-c/social_c.h @@ -264,7 +264,7 @@ typedef struct XblSocialRelationshipChangeEventArgs /// /// /// This handle is used by other APIs to get the social relationship objects and to get -/// the next page of results from the service if there is is one. +/// the next page of results from the service if there is one. /// The handle must be closed using when the result is no longer needed. /// typedef struct XblSocialRelationshipResult* XblSocialRelationshipResultHandle; diff --git a/Include/xsapi-c/social_manager_c.h b/Include/xsapi-c/social_manager_c.h index 7b6739b3..32da9fe8 100644 --- a/Include/xsapi-c/social_manager_c.h +++ b/Include/xsapi-c/social_manager_c.h @@ -261,7 +261,7 @@ typedef struct XblSocialManagerPresenceTitleRecord XblPresenceDeviceType deviceType; /// - /// Whether or not this is the primary primary presence record. + /// Whether or not this is the primary presence record. /// bool isPrimary; } XblSocialManagerPresenceTitleRecord; @@ -515,7 +515,7 @@ typedef const XblSocialManagerUser* const* XblSocialManagerUserPtrArray; /// STDAPI XblSocialManagerUserGroupGetUsers( _In_ XblSocialManagerUserGroupHandle group, - _Outptr_ XblSocialManagerUserPtrArray* users, + _Outptr_result_maybenull_ XblSocialManagerUserPtrArray* users, _Out_ size_t* usersCount ) XBL_NOEXCEPT; @@ -537,7 +537,7 @@ STDAPI XblSocialManagerUserGroupGetUsers( /// STDAPI XblSocialManagerUserGroupGetUsersTrackedByGroup( _In_ XblSocialManagerUserGroupHandle group, - _Outptr_ const uint64_t** trackedUsers, + _Outptr_result_maybenull_ const uint64_t** trackedUsers, _Out_ size_t* trackedUsersCount ) XBL_NOEXCEPT; diff --git a/Include/xsapi-c/title_storage_c.h b/Include/xsapi-c/title_storage_c.h index e7177164..25f59256 100644 --- a/Include/xsapi-c/title_storage_c.h +++ b/Include/xsapi-c/title_storage_c.h @@ -237,7 +237,7 @@ STDAPI_(void) XblTitleStorageBlobMetadataResultCloseHandle( /// Gets title storage quota information for the specified service configuration and storage type. /// /// An xbox live context handle created with XblContextCreateHandle. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The storage type to get quota information for. /// Caller allocated AsyncBlock. /// HRESULT return code for this API operation. @@ -275,7 +275,7 @@ STDAPI XblTitleStorageGetQuotaResult( /// Gets a list of blob metadata objects under a given path for the specified service configuration, storage type and storage ID. /// /// An xbox live context handle created with XblContextCreateHandle. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The storage type to get blob metadata objects for. /// The root path to enumerate. Results will be for blobs contained in this path and all subpaths. (Optional) /// The Xbox User ID of the title storage to enumerate. Ignored when enumerating GlobalStorage, so passing 0 is acceptable. (Optional) diff --git a/Include/xsapi-c/user_statistics_c.h b/Include/xsapi-c/user_statistics_c.h index c9795817..c3f1db52 100644 --- a/Include/xsapi-c/user_statistics_c.h +++ b/Include/xsapi-c/user_statistics_c.h @@ -130,7 +130,7 @@ typedef struct XblStatisticChangeEventArgs /// /// Xbox live context for the local user. /// The Xbox User ID of the player to get statistics for. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The name of the statistic to return. /// The AsyncBlock for this operation. /// HRESULT return code for this API operation. @@ -182,7 +182,7 @@ STDAPI XblUserStatisticsGetSingleUserStatisticResult( /// /// Xbox live context for the local user. /// The Xbox User ID of the player to get statistics for. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// A collection of statistic names to lookup. /// The number of statistic names. /// The AsyncBlock for this operation. @@ -239,7 +239,7 @@ STDAPI XblUserStatisticsGetSingleUserStatisticsResult( /// Xbox live context for the local user. /// A list of the user Xbox user IDs to get stats for. /// The number of Xbox user IDs. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// A collection of statistic names to lookup. /// The number of statistic names. /// The AsyncBlock for this operation. @@ -361,7 +361,7 @@ STDAPI XblUserStatisticsGetMultipleUserStatisticsForMultipleServiceConfiguration /// /// Xbox live context for the local user. /// The Xbox User ID of the player requesting the subscription. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// The name of the statistic to subscribe to. /// Passes back an XblRealTimeActivitySubscriptionHandle object that contains the state of the subscription. /// You can register an event handler for statistic changes by calling XblUserStatisticsAddStatisticChangedHandler(). @@ -432,7 +432,7 @@ STDAPI_(void) XblUserStatisticsRemoveStatisticChangedHandler( /// Xbox live context for the local user. /// Array of XboxUserIDs for whom to track the provided stats. /// Length of xboxUserIds array. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// Array of statistic names for which real-time updates will be received. /// Length of statisticNames array. /// HRESULT return code for this API operation. @@ -456,7 +456,7 @@ STDAPI XblUserStatisticsTrackStatistics( /// Xbox live context for the local user. /// Array of XboxUserIDs for whom to stop tracking the provided stats. /// Length of xboxUserIds array. -/// The service configuration ID (SCID) of the title. +/// The Service Configuration ID (SCID) for the title. The SCID is considered case sensitive so paste it directly from the Partner Center. /// Array of statistic names for which real-time updates are no longer needed. /// Length of statisticNames array. /// HRESULT return code for this API operation. diff --git a/Include/xsapi-c/xbox_live_context_settings_c.h b/Include/xsapi-c/xbox_live_context_settings_c.h index 456df9a6..596fb319 100644 --- a/Include/xsapi-c/xbox_live_context_settings_c.h +++ b/Include/xsapi-c/xbox_live_context_settings_c.h @@ -53,7 +53,7 @@ STDAPI XblContextSettingsSetLongHttpTimeout( /// The default for http_timeout_window is 20 seconds and can be changed using XblContextSettingsSetHttpTimeoutWindow. /// HRESULT return code for this API operation. /// -/// If the service returns an an HTTP error with a "Retry-After" header, then all future calls to that API will +/// If the service returns an HTTP error with a "Retry-After" header, then all future calls to that API will /// immediately fail with the original error without contacting the service until the "Retry-After" time has been reached. ///
/// Idempotent service calls are retried when a network error occurs or the server responds with one of these HTTP status codes:
@@ -74,7 +74,7 @@ STDAPI XblContextSettingsGetHttpRetryDelay( /// /// Xbox live context that the settings are associated with. /// The retry delay in seconds. -/// Retries are delayed using a exponential back off. +/// Retries are delayed using an exponential back off. /// By default, it will delay 2 seconds then the next retry will delay 4 seconds, then 8 seconds, /// and so on up to a max of 1 min until either the call succeeds or the http_timeout_window /// is reached, at which point the call will fail. @@ -82,7 +82,7 @@ STDAPI XblContextSettingsGetHttpRetryDelay( /// The default for http_timeout_window is 20 seconds and can be changed using XblContextSettingsSetHttpTimeoutWindow. /// HRESULT return code for this API operation. /// -/// If the service returns an an HTTP error with a "Retry-After" header, then all future calls to that API will +/// If the service returns an HTTP error with a "Retry-After" header, then all future calls to that API will /// immediately fail with the original error without contacting the service until the "Retry-After" time has been reached. ///
/// Idempotent service calls are retried when a network error occurs or the server responds with one of these HTTP status codes:
diff --git a/Include/xsapi-c/xbox_live_global_c.h b/Include/xsapi-c/xbox_live_global_c.h index 1d6de82c..9d13b9f5 100644 --- a/Include/xsapi-c/xbox_live_global_c.h +++ b/Include/xsapi-c/xbox_live_global_c.h @@ -90,7 +90,7 @@ STDAPI XblMemSetFunctions( /// /// Set to the current allocation callback. /// Returns the default routine if not previously set. -/// Set to the to the current memory free callback. +/// Set to the current memory free callback. /// Returns the default routine if not previously set. /// HRESULT return code for this API operation. /// @@ -120,7 +120,9 @@ typedef struct XblInitArgs #if !(HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_UWP) /// - /// The service configuration Id for the app. + /// The Service Configuration ID (SCID) for the app. + /// You can find it on Partner Center in the Game Setup page under Identity details. + /// This string is considered case sensitive so paste it directly from the Partner Center /// _Field_z_ const char* scid; @@ -270,7 +272,7 @@ enum class XblConfigSetting : uint32_t /// The config settings value to be passed down. /// HRESULT return code for this API operation. /// -/// The asserts will not fire in RETAIL sandbox, and this setting has has no affect in RETAIL sandboxes. +/// The asserts will not fire in RETAIL sandbox, and this setting has no affect in RETAIL sandboxes. /// It is best practice to not call this API, and instead adjust the calling pattern but this is provided /// as a temporary way to get unblocked while in early stages of game development. /// @@ -279,9 +281,9 @@ STDAPI_(void) XblDisableAssertsForXboxLiveThrottlingInDevSandboxes( ) XBL_NOEXCEPT; /// -/// For advanced scenarios where a common scid and title Id are needed for cross platform experiences. +/// For advanced scenarios where a common Service Configuration ID (SCID) and title Id are needed for cross platform experiences. /// -/// Override scid to be used by multiplayer manager. +/// Override Service Configuration ID (SCID) to be used by multiplayer manager. This SCID is considered case sensitive so paste it directly from the Partner Center /// Override title Id to be used by multiplayer manager. /// HRESULT return code for this API operation. /// diff --git a/Include/xsapi-cpp/impl/achievements.hpp b/Include/xsapi-cpp/impl/achievements.hpp index 1676ed25..6e10f957 100644 --- a/Include/xsapi-cpp/impl/achievements.hpp +++ b/Include/xsapi-cpp/impl/achievements.hpp @@ -298,12 +298,18 @@ bool achievement::is_revoked() const achievements_result::achievements_result(XblAchievementsResultHandle handle) { - XblAchievementsResultDuplicateHandle(handle, &m_handle); + if (handle != nullptr) + { + XblAchievementsResultDuplicateHandle(handle, &m_handle); + } } achievements_result::achievements_result(const achievements_result& other) { - XblAchievementsResultDuplicateHandle(other.m_handle, &m_handle); + if (other.m_handle != nullptr) + { + XblAchievementsResultDuplicateHandle(other.m_handle, &m_handle); + } } achievements_result& achievements_result::operator=(achievements_result other) diff --git a/Include/xsapi-cpp/impl/http_call.hpp b/Include/xsapi-cpp/impl/http_call.hpp index abd4168a..56794be7 100644 --- a/Include/xsapi-cpp/impl/http_call.hpp +++ b/Include/xsapi-cpp/impl/http_call.hpp @@ -307,12 +307,14 @@ void http_call::set_request_body( _In_ const string_t& value ) { - XblHttpCallRequestSetRequestBodyString(m_callHandle, Utils::StringFromStringT(value).c_str()); + auto convertedValue = Utils::StringFromStringT(value); + XblHttpCallRequestSetRequestBodyString(m_callHandle, convertedValue.c_str()); } void http_call::set_request_body( _In_ const web::json::value& value ) { - XblHttpCallRequestSetRequestBodyString(m_callHandle, Utils::StringFromStringT(value.serialize()).c_str()); + auto convertedValue = Utils::StringFromStringT(value.serialize()); + XblHttpCallRequestSetRequestBodyString(m_callHandle, convertedValue.c_str()); } void http_call::set_request_body( @@ -331,10 +333,13 @@ void http_call::set_custom_header( _In_ const string_t& Value ) { + const auto headerName = Utils::StringFromStringT(Name); + const auto headerValue = Utils::StringFromStringT(Value); + XblHttpCallRequestSetHeader( m_callHandle, - Utils::StringFromStringT(Name).c_str(), - Utils::StringFromStringT(Value).c_str(), + headerName.c_str(), + headerValue.c_str(), false ); } diff --git a/Include/xsapi-cpp/impl/public_utils.h b/Include/xsapi-cpp/impl/public_utils.h index 31149942..2f167b80 100644 --- a/Include/xsapi-cpp/impl/public_utils.h +++ b/Include/xsapi-cpp/impl/public_utils.h @@ -295,7 +295,7 @@ struct Utils { if (jsonString) { - return web::json::value::parse(StringTFromUtf8(jsonString)); + return web::json::value::parse(Utils::StringTFromUtf8(jsonString)); } } catch (web::json::json_exception) diff --git a/Include/xsapi-cpp/impl/service_call_logging_config.hpp b/Include/xsapi-cpp/impl/service_call_logging_config.hpp new file mode 100644 index 00000000..f1854d62 --- /dev/null +++ b/Include/xsapi-cpp/impl/service_call_logging_config.hpp @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#pragma once + +#include "public_utils.h" + +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN + +#if HC_PLATFORM_IS_MICROSOFT + +std::shared_ptr service_call_logging_config::get_singleton_instance() +{ + static std::shared_ptr s_instance = std::shared_ptr(new service_call_logging_config); + return s_instance; +} + +void service_call_logging_config::enable() {} +void service_call_logging_config::disable() {} +#if HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_UWP || XSAPI_UNIT_TESTS +void service_call_logging_config::_Register_for_protocol_activation() {} +#endif + +#endif + +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Include/xsapi-cpp/impl/system.hpp b/Include/xsapi-cpp/impl/system.hpp new file mode 100644 index 00000000..04bbeb92 --- /dev/null +++ b/Include/xsapi-cpp/impl/system.hpp @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#pragma once + +#include "public_utils.h" + +NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN + +std::shared_ptr xbox_live_services_settings::get_singleton_instance(_In_ bool createIfRequired) +{ + UNREFERENCED_PARAMETER(createIfRequired); + + static std::shared_ptr instance = std::shared_ptr(new xbox_live_services_settings); + return instance; +} + +void xbox_live_services_settings::set_memory_allocation_hooks( + _In_ const std::function<_Ret_maybenull_ _Post_writable_byte_size_(dwSize) void*(_In_ size_t dwSize)>& memAllocHandler, + _In_ const std::function& memFreeHandler +) +{ + static std::function allocHook{ nullptr }; + static std::function freeHook{ nullptr }; + + if (memAllocHandler != nullptr && memFreeHandler != nullptr) + { + allocHook = memAllocHandler; + freeHook = memFreeHandler; + + XblMemSetFunctions( + [](size_t size, HCMemoryType) + { + return allocHook(size); + }, + [](void* pointer, HCMemoryType) + { + freeHook(pointer); + } + ); + } + else if (memAllocHandler == nullptr && memFreeHandler == nullptr) + { + XblMemSetFunctions(nullptr, nullptr); + } +} + + +function_context xbox_live_services_settings::add_logging_handler( + std::function handler +) +{ + UNREFERENCED_PARAMETER(handler); + return function_context{}; +} + +void xbox_live_services_settings::remove_logging_handler(_In_ function_context context) +{ + UNREFERENCED_PARAMETER(context); +} + +xbox_services_diagnostics_trace_level xbox_live_services_settings::diagnostics_trace_level() const +{ + HCTraceLevel traceLevel{}; + HCSettingsGetTraceLevel(&traceLevel); + + switch (traceLevel) + { + case HCTraceLevel::Off: return xbox_services_diagnostics_trace_level::off; + case HCTraceLevel::Error: return xbox_services_diagnostics_trace_level::error; + case HCTraceLevel::Warning: return xbox_services_diagnostics_trace_level::warning; + case HCTraceLevel::Important: return xbox_services_diagnostics_trace_level::info; + case HCTraceLevel::Verbose: return xbox_services_diagnostics_trace_level::verbose; + default: return xbox_services_diagnostics_trace_level::off; + } +} + +void xbox_live_services_settings::set_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level value) +{ + HCTraceLevel traceLevel{ HCTraceLevel::Off }; + switch (value) + { + case xbox_services_diagnostics_trace_level::off: traceLevel = HCTraceLevel::Off; break; + case xbox_services_diagnostics_trace_level::error: traceLevel = HCTraceLevel::Error; break; + case xbox_services_diagnostics_trace_level::warning: traceLevel = HCTraceLevel::Warning; break; + case xbox_services_diagnostics_trace_level::info: traceLevel = HCTraceLevel::Information; break; + case xbox_services_diagnostics_trace_level::verbose: traceLevel = HCTraceLevel::Verbose; break; + default: break; + } + HCSettingsSetTraceLevel(traceLevel); +} + +function_context xbox_live_services_settings::add_wns_handler(_In_ const std::function& handler) +{ + UNREFERENCED_PARAMETER(handler); + return function_context{}; +} + +void xbox_live_services_settings::remove_wns_handler(_In_ function_context context) +{ + UNREFERENCED_PARAMETER(context); +} + +NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END \ No newline at end of file diff --git a/Include/xsapi-cpp/multiplayer.h b/Include/xsapi-cpp/multiplayer.h index 416084e6..6260cfd0 100644 --- a/Include/xsapi-cpp/multiplayer.h +++ b/Include/xsapi-cpp/multiplayer.h @@ -252,7 +252,7 @@ enum class multiplayer_session_member_status /// /// The member is inactive in the current title. /// The member may be active in another title as specified by ActiveTitleId. - /// If a inactive member doesn't mark themselves as Active within the MemberInactiveTimeout they will be removed from the session. + /// If an inactive member doesn't mark themselves as Active within the MemberInactiveTimeout they will be removed from the session. /// inactive, @@ -741,7 +741,7 @@ public: inline std::chrono::milliseconds member_reserved_time_out() const; /// - /// If a inactive member reservation does not become active within this timeout, then inactive member is removed from the session. + /// If an inactive member reservation does not become active within this timeout, then the inactive member is removed from the session. /// inline std::chrono::milliseconds member_inactive_timeout() const; @@ -1689,7 +1689,7 @@ public: inline utility::datetime start_time() const; /// - /// If any timeouts are in progress, this is the date when the the next timer will fire. + /// If any timeouts are in progress, this is the date when the next timer will fire. /// inline utility::datetime date_of_next_timer() const; @@ -1727,7 +1727,7 @@ public: inline multiplayer_session_change_types subscribed_change_types() const; /// - /// Host candidates are a ordered list of device tokens, ordered by preference as specified by MultiplayerSessionConstants::PeerToHostRequirements::HostSelectionMetric. + /// Host candidates are an ordered list of device tokens, ordered by preference as specified by MultiplayerSessionConstants::PeerToHostRequirements::HostSelectionMetric. /// inline std::vector host_candidates() const; @@ -2085,7 +2085,7 @@ public: /// Call multiplayer_service::write_session after this to write batched local changes to the service. /// If this is called without multiplayer_service::write_session, this will only change the local session object but does not commit it to the service. /// Set the current user to active or inactive. - /// You cannot set the the user to reserved or ready in this manner. + /// You cannot set the user to reserved or ready in this manner. /// Use AddMemberReservation() to add a member reservation. /// The member must first be joined to the session. /// diff --git a/Include/xsapi-cpp/service_call_logging_config.h b/Include/xsapi-cpp/service_call_logging_config.h index 72a92f75..bf1d370b 100644 --- a/Include/xsapi-cpp/service_call_logging_config.h +++ b/Include/xsapi-cpp/service_call_logging_config.h @@ -12,34 +12,34 @@ class service_call_logging_config public: /// - /// Gets the service_call_logger singleton instance + /// Deprecated. Service call logging feature is no longer supported. /// - static std::shared_ptr get_singleton_instance(); + _XSAPICPP_DEPRECATED inline static std::shared_ptr get_singleton_instance(); /// - /// Enables the tracking of service calls + /// Deprecated. Service call logging feature is no longer supported. /// - void enable(); + _XSAPICPP_DEPRECATED inline void enable(); /// - /// Disables the tracking of service calls + /// Deprecated. Service call logging feature is no longer supported. /// - void disable(); + _XSAPICPP_DEPRECATED inline void disable(); #if HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_UWP || XSAPI_UNIT_TESTS /// - /// Internal API - /// Enables Logs to be enabled/disabled through protocol activation + /// Deprecated /// - void _Register_for_protocol_activation(); + _XSAPICPP_DEPRECATED inline void _Register_for_protocol_activation(); #endif private: - service_call_logging_config(); - service_call_logging_config(const service_call_logging_config&); - void operator=(const service_call_logging_config&); - friend struct ::XblContext; + service_call_logging_config() = default; + service_call_logging_config(const service_call_logging_config&) = delete; + void operator=(const service_call_logging_config&) = delete; }; #endif // HC_PLATFORM_IS_MICROSOFT -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END + +#include "impl/service_call_logging_config.hpp" \ No newline at end of file diff --git a/Include/xsapi-cpp/system.h b/Include/xsapi-cpp/system.h index 2c1ea32f..019198c5 100644 --- a/Include/xsapi-cpp/system.h +++ b/Include/xsapi-cpp/system.h @@ -34,14 +34,6 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN /// namespace system { - // Forward declaration - class sign_out_completed_event_args; - class user_impl; - class token_and_signature_result_internal; - class user_factory; - class xbox_live_server_impl; - class auth_config; - class xbox_live_wns_event_args { public: @@ -85,15 +77,12 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN /// /// Gets the singleton instance /// - static std::shared_ptr get_singleton_instance(_In_ bool createIfRequired = true); + inline static std::shared_ptr get_singleton_instance(_In_ bool createIfRequired = true); /// /// Used by titles to register memory allocation hooks that are used by XSAPI when it /// needs to allocate a large block of memory such as SocialManager which uses a large block /// of memory to keep track of the friends list. - /// - /// Note that not all memory that XSAPI uses goes through this allocator (for example std::string), - /// but these allocations are typically small and transient. /// /// The title's allocation function. Input is size of memory block that's being requested. Return is pointer to the allocated memory block /// The title's memory free function. Input is address of memory to free @@ -103,86 +92,48 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN /// It is important to provide an implementation for both memAllocHandler and memFreeHandler if you hook them; /// hooking only one of them will be considered an error. /// - static void set_memory_allocation_hooks( + inline static void set_memory_allocation_hooks( _In_ const std::function<_Ret_maybenull_ _Post_writable_byte_size_(dwSize) void*(_In_ size_t dwSize)>& memAllocHandler, _In_ const std::function& memFreeHandler ); /// - /// Registers to receive logging messages for levels that are enabled. Event handlers will receive the level, category, and content of the message. + /// Deprecated. XSAPI is using libHttpClient logging. A logging handler can be added using HCTraceSetClientCallback. /// - /// The event handler function to call. - /// - /// A function_context object that can be used to unregister the event handler. - /// - function_context add_logging_handler(_In_ std::function handler); + _XSAPICPP_DEPRECATED inline function_context add_logging_handler(_In_ std::function handler); /// - /// Unregisters from receiving logging messages. + /// Deprecated. See above. /// - /// The function_context object that was returned when the event handler was registered. - void remove_logging_handler(_In_ function_context context); + _XSAPICPP_DEPRECATED inline void remove_logging_handler(_In_ function_context context); /// /// Indicates the level of debug messages to send to the debugger's Output window. /// - xbox_services_diagnostics_trace_level diagnostics_trace_level() const; + inline xbox_services_diagnostics_trace_level diagnostics_trace_level() const; /// /// Sets the level of debug messages to send to the debugger's Output window. /// - void set_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level value); + inline void set_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level value); /// - /// Registers to receive Windows Push Notification Service(WNS) events. Event handlers will receive the xbox user id and notification type. + /// Deprecated. Registering WNS callbacks though XSAPI is no longer supported. /// - /// The event handler function to call. - /// - /// A function_context object that can be used to unregister the event handler. - /// - function_context add_wns_handler(_In_ const std::function& handler); + _XSAPICPP_DEPRECATED inline function_context add_wns_handler(_In_ const std::function& handler); /// - /// Unregisters from receiving Windows Push Notification Service(WNS) events. + /// Deprecated. Registering WNS callbacks though XSAPI is no longer supported. /// - /// The function_context object that was returned when the event handler was registered. - void remove_wns_handler(_In_ function_context context); - - /// - /// Internal function - /// - void _Raise_logging_event(_In_ xbox_services_diagnostics_trace_level level, _In_ const std::string& category, _In_ const std::string& message); - - /// - /// Internal function - /// - void _Raise_wns_event(_In_ const string_t& xbox_user_id, _In_ const string_t& nofitication_type, _In_ const string_t& content); - - /// - /// Internal function - /// - bool _Is_at_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level level); + _XSAPICPP_DEPRECATED inline void remove_wns_handler(_In_ function_context context); private: - xbox_live_services_settings(); - - void set_log_level_from_diagnostics_trace_level(); - - xbox_services_diagnostics_trace_level m_traceLevel; - std::mutex m_loggingWriteLock; - std::unordered_map> m_loggingHandlers; - uint32_t m_loggingHandlersCounter{ 1 }; - - std::mutex m_wnsEventLock; - std::unordered_map> m_wnsHandlers; - uint32_t m_wnsHandlersCounter{ 1 }; - - friend class xsapi_memory; - friend void *custom_mem_alloc_wrapper(_In_ size_t size, _In_ uint32_t memoryType); - friend void custom_mem_free_wrapper(_In_ void *pointer, _In_ uint32_t memoryType); + xbox_live_services_settings() = default; }; } // namespace system NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - +#if !XSAPI_NO_PPL +#include "impl/system.hpp" +#endif diff --git a/Include/xsapi-cpp/xbox_live_context_settings.h b/Include/xsapi-cpp/xbox_live_context_settings.h index 85edfdc9..adb438bd 100644 --- a/Include/xsapi-cpp/xbox_live_context_settings.h +++ b/Include/xsapi-cpp/xbox_live_context_settings.h @@ -111,13 +111,13 @@ public: /// /// Gets the HTTP retry delay in seconds. /// - /// Retries are delayed using a exponential back off. By default, it will delay 2 seconds then the + /// Retries are delayed using an exponential back off. By default, it will delay 2 seconds then the /// next retry will delay 4 seconds, then 8 seconds, and so on up to a max of 1 min until either /// the call succeeds or the http_timeout_window is reached, at which point the call will fail. /// The delay is also jittered between the current and next delay to spread out service load. /// The default for http_timeout_window is 20 seconds and can be changed using set_http_timeout_window() /// - /// If the service returns an an HTTP error with a "Retry-After" header, then all future calls to that API + /// If the service returns an HTTP error with a "Retry-After" header, then all future calls to that API /// will immediately fail with the original error without contacting the service until the "Retry-After" /// time has been reached. /// @@ -134,13 +134,13 @@ public: /// /// Sets the HTTP retry delay in seconds. The default and minimum delay is 2 seconds. /// - /// Retries are delayed using a exponential back off. By default, it will delay 2 seconds then the + /// Retries are delayed using an exponential back off. By default, it will delay 2 seconds then the /// next retry will delay 4 seconds, then 8 seconds, and so on up to a max of 1 min until either /// the call succeeds or the http_timeout_window is reached, at which point the call will fail. /// The delay is also jittered between the current and next delay to spread out service load. /// The default for http_timeout_window is 20 seconds and can be changed using set_http_timeout_window() /// - /// If the service returns an an HTTP error with a "Retry-After" header, then all future calls to that API + /// If the service returns an HTTP error with a "Retry-After" header, then all future calls to that API /// will immediately fail with the original error without contacting the service until the "Retry-After" /// time has been reached. /// @@ -211,7 +211,7 @@ public: /// /// Disables asserts for Xbox Live throttling in dev sandboxes. - /// The asserts will not fire in RETAIL sandbox, and this setting has has no affect in RETAIL sandboxes. + /// The asserts will not fire in RETAIL sandbox, and this setting has no affect in RETAIL sandboxes. /// It is best practice to not call this API, and instead adjust the calling pattern but this is provided /// as a temporary way to get unblocked while in early stages of game development. /// diff --git a/Source/Services/Achievements/Manager/achievements_manager_api.cpp b/Source/Services/Achievements/Manager/achievements_manager_api.cpp index 8713af0f..a0fba776 100644 --- a/Source/Services/Achievements/Manager/achievements_manager_api.cpp +++ b/Source/Services/Achievements/Manager/achievements_manager_api.cpp @@ -156,12 +156,12 @@ STDAPI XblAchievementsManagerGetAchievement( _Outptr_result_maybenull_ XblAchievementsManagerResultHandle* achievementResult ) XBL_NOEXCEPT { + RETURN_HR_INVALIDARGUMENT_IF(achievementId == nullptr || achievementResult == nullptr); + RETURN_HR_INVALIDARGUMENT_IF_EMPTY_STRING(achievementId); + *achievementResult = nullptr; + return ApiImpl([&](AchievementsManager& achievementsManager) { - RETURN_HR_INVALIDARGUMENT_IF(achievementId == nullptr || achievementResult == nullptr); - RETURN_HR_INVALIDARGUMENT_IF_EMPTY_STRING(achievementId); - *achievementResult = nullptr; - auto achievement = achievementsManager.GetAchievement(xboxUserId, achievementId); if (Failed(achievement)) { diff --git a/Source/Services/Achievements/Manager/achievements_manager_internal.cpp b/Source/Services/Achievements/Manager/achievements_manager_internal.cpp index 12504b82..359fac79 100644 --- a/Source/Services/Achievements/Manager/achievements_manager_internal.cpp +++ b/Source/Services/Achievements/Manager/achievements_manager_internal.cpp @@ -8,7 +8,7 @@ using namespace xbox::services; -XblAchievementsManagerResult::XblAchievementsManagerResult(const XblAchievement & achievement) +XblAchievementsManagerResult::XblAchievementsManagerResult(_In_ const XblAchievement & achievement) : m_achievements({ achievement }), m_explicitCleanup(false), m_achievementsData(nullptr), @@ -16,7 +16,7 @@ XblAchievementsManagerResult::XblAchievementsManagerResult(const XblAchievement { } -XblAchievementsManagerResult::XblAchievementsManagerResult(Vector& achievements, bool explicitCleanup) +XblAchievementsManagerResult::XblAchievementsManagerResult(_In_ Vector& achievements, _In_ bool explicitCleanup) : m_achievements(std::move(achievements)), m_achievementsData(m_achievements.data()), m_achievementsCount(m_achievements.size()), @@ -24,7 +24,7 @@ XblAchievementsManagerResult::XblAchievementsManagerResult(Vector AchievementsManagerUser::GetAchievement(const String & id) +Result AchievementsManagerUser::GetAchievement(_In_ const String & id) { if (m_userAchievements.find(id) == m_userAchievements.end()) { @@ -346,7 +346,7 @@ uint64_t AchievementsManagerUser::GetAchievementCount() const return m_userAchievements.size(); } -Result AchievementsManagerUser::CanUpdateAchievement(const String & achievementId, uint8_t progress) +Result AchievementsManagerUser::CanUpdateAchievement(_In_ const String & achievementId, _In_ uint8_t progress) { if (m_userAchievements.find(achievementId) == m_userAchievements.end()) { @@ -386,10 +386,10 @@ Result AchievementsManagerUser::CanUpdateAchievement(const String & achiev ); return { E_INVALIDARG, errorMsg }; } - return true; + return S_OK; } -Result AchievementsManagerUser::UpdateAchievement(const String& achievementId, uint8_t percent) +Result AchievementsManagerUser::UpdateAchievement(_In_ const String& achievementId, _In_ uint8_t percent) { return m_xblContext->AchievementsService()->UpdateAchievement( m_xuid, @@ -422,21 +422,21 @@ ProgressValueType IsNumber(const char* str) { char* p = nullptr; - strtoul(str, &p, 0); + (void)strtoul(str, &p, 0); if (p == nullptr) { return ProgressValueType::UnsignedLong; } // If it couldn't be represented as an unsigned long, check to see if it can be signed next. - strtol(str, &p, 0); + (void)strtol(str, &p, 0); if (p == nullptr) { return ProgressValueType::SignedLong; } // If neither of those, then either it is a floating point number, or it is non-numeric. - strtod(str, &p); + (void)strtod(str, &p); if (p == nullptr) { return ProgressValueType::FloatingPoint; @@ -789,7 +789,7 @@ Vector GenerateEventFromAchievementDiff(uint64_t xu return generatedEvents; } -HRESULT AchievementsManagerUser::FetchAchievements(AsyncContext async) +HRESULT AchievementsManagerUser::FetchAchievements(_In_ AsyncContext async) { constexpr uint32_t achievementsPerFetch = 100; @@ -818,10 +818,10 @@ HRESULT AchievementsManagerUser::FetchAchievements(AsyncContext async) } HRESULT AchievementsManagerUser::HandleAchievementsResults( - Result> result, - uint32_t achievementsPerFetch, - AsyncContext async, - Vector fetchedAchievements + _In_ Result> result, + _In_ uint32_t achievementsPerFetch, + _In_ AsyncContext async, + _In_ Vector fetchedAchievements ) { if (Succeeded(result)) @@ -1015,7 +1015,7 @@ HRESULT AchievementsManager::CleanUpAchievementCopyForResult(XblAchievement& ach return S_OK; } -XblAchievement AchievementsManager::DeepCopyAchievement(const XblAchievement & other) +XblAchievement AchievementsManager::DeepCopyAchievement(_In_ const XblAchievement & other) { XblAchievement copy { @@ -1144,7 +1144,7 @@ Vector AchievementsManager::DeepCopyAchievements(const Vector lock{ m_mutex }; @@ -1321,7 +1321,7 @@ Result AchievementsManager::GetAchievement( return m_localUsers[xuid]->GetAchievement(achievementId); } -Result> AchievementsManager::GetAchievements(uint64_t xuid) +Result> AchievementsManager::GetAchievements(_In_ uint64_t xuid) { if (m_localUsers.find(xuid) == m_localUsers.end()) { @@ -1390,17 +1390,17 @@ Result AchievementsManager::UpdateAchievement( return localUser->UpdateAchievement(achievementId, progress); } -bool AchievementsManager::HasUser(uint64_t xuid) const +bool AchievementsManager::HasUser(_In_ uint64_t xuid) const { return m_localUsers.find(xuid) != m_localUsers.end(); } -bool AchievementsManager::IsUserInitialized(uint64_t xuid) +bool AchievementsManager::IsUserInitialized(_In_ uint64_t xuid) { return m_localUsers[xuid]->IsInitialized(); } -uint64_t AchievementsManager::GetUserAchievementCount(uint64_t xuid) +uint64_t AchievementsManager::GetUserAchievementCount(_In_ uint64_t xuid) { return m_localUsers[xuid]->GetAchievementCount(); } diff --git a/Source/Services/Achievements/Manager/achievements_manager_internal.h b/Source/Services/Achievements/Manager/achievements_manager_internal.h index af20fe1a..744d30ff 100644 --- a/Source/Services/Achievements/Manager/achievements_manager_internal.h +++ b/Source/Services/Achievements/Manager/achievements_manager_internal.h @@ -22,8 +22,8 @@ struct XblAchievementsManagerResult : public xbox::services::RefCounter, public { public: XblAchievementsManagerResult(_In_ const XblAchievement& achievement); - XblAchievementsManagerResult(_In_ Vector& achievements, bool explicitCleanup = false); - XblAchievementsManagerResult(_In_ XblAchievement* achievements, _In_ size_t achievementCount, bool explicitCleanup = false); + XblAchievementsManagerResult(_In_ Vector& achievements, _In_ bool explicitCleanup = false); + XblAchievementsManagerResult(_In_ XblAchievement* achievements, _In_ size_t achievementCount, _In_ bool explicitCleanup = false); virtual ~XblAchievementsManagerResult(); const Vector& Achievements() const; @@ -151,17 +151,17 @@ private: bool m_isInitialized = false; Map m_userAchievements; - XblAchievement* m_achievementCache; - uint64_t m_xuid; + XblAchievement* m_achievementCache{ nullptr }; + uint64_t m_xuid{ 0 }; Vector m_eventsToProcess; Vector m_generatedEvents; std::shared_ptr m_xblContext; - XblFunctionContext m_achievementProgressToken; - XblFunctionContext m_rtaResyncToken; - XblFunctionContext m_rtaConnectionToken; + XblFunctionContext m_achievementProgressToken{ 0 }; + XblFunctionContext m_rtaResyncToken{ 0 }; + XblFunctionContext m_rtaConnectionToken{ 0 }; std::shared_ptr m_rtaManager; diff --git a/Source/Services/Achievements/achievement_service_internal.cpp b/Source/Services/Achievements/achievement_service_internal.cpp index 36565807..265ae2c9 100644 --- a/Source/Services/Achievements/achievement_service_internal.cpp +++ b/Source/Services/Achievements/achievement_service_internal.cpp @@ -117,20 +117,14 @@ HRESULT AchievementsService::UpdateAchievement( #if HC_PLATFORM == HC_PLATFORM_XDK { - auto xsapiSingleton = get_xsapi_singleton(); - if (!xsapiSingleton) + auto state = GlobalState::Get(); + if (!state) { - return utils::convert_xbox_live_error_code_to_hresult(xbl_error_code::runtime_error); + return E_XBL_NOT_INITIALIZED; } - std::lock_guard lock(xsapiSingleton->m_achievementServiceInitLock); - if (!xsapiSingleton->m_bHasAchievementServiceInitialized) + // Register ETX provider if it hasn't been registered yet + if (XSAPI_Update_Achievement_Handle == 0) { - HRESULT hr = CoCreateGuid(&xsapiSingleton->m_eventPlayerSessionId); - if (FAILED(hr)) - { - return hr; - } - string_t wScid = utils::string_t_from_internal_string(lowercaseScid); std::error_code errC = utils::guid_from_string(wScid, const_cast(&XSAPI_Update_Achievement_Provider.Guid), false); if (errC) @@ -138,23 +132,10 @@ HRESULT AchievementsService::UpdateAchievement( return utils::convert_xbox_live_error_code_to_hresult(errC); } - CHAR strTitleId[16] = ""; - sprintf_s(strTitleId, "%0.8X", titleId); - - std::stringstream ss; - ss << "XSAPI_"; - ss << strTitleId; - xsapiSingleton->m_eventProviderName = ss.str(); - XSAPI_Update_Achievement_Provider.Name = xsapiSingleton->m_eventProviderName.c_str(); + XSAPI_Update_Achievement_Provider.Name = state->AchievementsProviderName().data(); ULONG errorCode = EtxRegister(&XSAPI_Update_Achievement_Provider, &XSAPI_Update_Achievement_Handle); - hr = HRESULT_FROM_WIN32(errorCode); - if (FAILED(hr)) - { - return hr; - } - - xsapiSingleton->m_bHasAchievementServiceInitialized = true; + RETURN_HR_IF_FAILED(HRESULT_FROM_WIN32(errorCode)); } } #endif @@ -277,7 +258,7 @@ ULONG AchievementsService::EventWriteAchievementUpdate( EtxFillCommonFields_v7(&eventData[0], scratch, EventWriteAchievementUpdate_ScratchSize); EventDataDescCreate(&eventData[1], userId, (ULONG)((wcslen(userId) + 1) * sizeof(WCHAR))); - EventDataDescCreate(&eventData[2], &get_xsapi_singleton()->m_eventPlayerSessionId, sizeof(GUID)); + EventDataDescCreate(&eventData[2], &GlobalState::Get()->AchievementsSessionId(), sizeof(GUID)); EventDataDescCreate(&eventData[3], achievementId, (ULONG)((wcslen(achievementId) + 1) * sizeof(WCHAR))); EventDataDescCreate(&eventData[4], &percentComplete, sizeof(percentComplete)); @@ -299,7 +280,7 @@ AchievementsService::WriteOfflineUpdateAchievement( { ULONG errorCode = EventWriteAchievementUpdate( utils::uint64_to_string_t(xboxLiveContextImpl->Xuid()).c_str(), - utils::string_t_from_internal_string(achievementId).c_str(), + convert::utf8_to_utf16(achievementId).c_str(), percentComplete ); HRESULT hr = HRESULT_FROM_WIN32(errorCode); @@ -559,7 +540,7 @@ String AchievementsService::GetAchievementsSubpath( path << xboxUserId; path << (")/achievements"); - subPathBuilder.append_path(utils::string_t_from_internal_string(path.str())); + subPathBuilder.append_path(path.str()); Stringstream titleQuery; auto &last = titleIds.back(); @@ -571,28 +552,28 @@ String AchievementsService::GetAchievementsSubpath( titleQuery << (","); } } - subPathBuilder.append_query(_T("titleId"), utils::string_t_from_internal_string(titleQuery.str())); + subPathBuilder.append_query("titleId", titleQuery.str()); if (type != XblAchievementType::All) { - subPathBuilder.append_query(_T("types"), utils::string_t_from_internal_string(EnumName(type))); + subPathBuilder.append_query("types", EnumName(type)); } if (unlockedOnly) { - subPathBuilder.append_query(_T("unlockedOnly=true")); + subPathBuilder.append_query("unlockedOnly=true"); } switch (orderBy) { case XblAchievementOrderBy::TitleId: { - subPathBuilder.append_query(_T("orderBy"), _T("title")); + subPathBuilder.append_query("orderBy", "title"); break; } case XblAchievementOrderBy::UnlockTime: { - subPathBuilder.append_query(_T("orderBy"), _T("unlocktime")); + subPathBuilder.append_query("orderBy", "unlocktime"); break; } default: break; @@ -605,7 +586,7 @@ String AchievementsService::GetAchievementsSubpath( continuationToken ); - return utils::internal_string_from_string_t(subPathBuilder.to_string()); + return subPathBuilder.to_string(); } void AchievementsService::CleanupAchievement(XblAchievement& a) @@ -874,7 +855,7 @@ Result AchievementsService::DeserializeReward( auto mediaAssetResult = DeserializeMediaAsset(json["mediaAsset"]); reward.mediaAsset = Make(mediaAssetResult.ExtractPayload()); - if (Failed(mediaAssetResult) || errc) + if (Failed(mediaAssetResult) || FAILED(errc)) { return Result{ reward, E_FAIL }; } @@ -971,7 +952,7 @@ Result AchievementsService::DeserializeAchievement( a.rewards = MakeArray(rewardsVector); a.rewardsCount = rewardsVector.size(); - std::chrono::seconds seconds; + std::chrono::seconds seconds{}; RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonStringTimespanInSeconds(json, "estimatedTime", seconds, true)); a.estimatedUnlockTime = seconds.count(); xsapi_internal_string deeplink; @@ -992,7 +973,7 @@ Result AchievementsService::DeserializeAchievement( } a.progression = progressionResult.ExtractPayload(); - if (Failed(progressionResult) || Failed(timeWindowResult) || errCode) + if (Failed(progressionResult) || Failed(timeWindowResult) || FAILED(errCode)) { CleanupAchievement(a); return Result{ E_FAIL }; diff --git a/Source/Services/Achievements/achievements_result.cpp b/Source/Services/Achievements/achievements_result.cpp index c5766b62..0cbc071f 100644 --- a/Source/Services/Achievements/achievements_result.cpp +++ b/Source/Services/Achievements/achievements_result.cpp @@ -43,7 +43,7 @@ Result> XblAchievementsResult::Deserializ } } - if (errCode) + if (FAILED(errCode)) { return Result>{ errCode }; } diff --git a/Source/Services/Common/Cpp/pch.cpp b/Source/Services/Common/Cpp/pch.cpp index 625d3839..3c8a183f 100644 --- a/Source/Services/Common/Cpp/pch.cpp +++ b/Source/Services/Common/Cpp/pch.cpp @@ -3,6 +3,8 @@ #include "pch.h" -#ifndef _LINK_WITH_CPPRESTSDK +#if !_LINK_WITH_CPPRESTSDK && HC_PLATFORM != HC_PLATFORM_GDK #include "cpprestsdk_impl.h" -#endif \ No newline at end of file +#endif +#include +#include "uri_impl.h" \ No newline at end of file diff --git a/Source/Services/Common/pch_common.h b/Source/Services/Common/pch_common.h index 4a7cdb55..cf5348d2 100644 --- a/Source/Services/Common/pch_common.h +++ b/Source/Services/Common/pch_common.h @@ -69,6 +69,9 @@ #include #include #include +#if HC_PLATFORM_IS_MICROSOFT +#include +#endif #include "httpClient/pal.h" #include "httpClient/httpClient.h" @@ -83,10 +86,23 @@ #include #include "http_headers.h" +#if HC_PLATFORM != HC_PLATFORM_GDK #include "cpprest/http_msg.h" +#endif #include "http_utils.h" +#if HC_PLATFORM == HC_PLATFORM_GDK +#include "HookedUri/uri.h" +#endif +#undef max // needed for the version of RapidJson we're using to avoid warnings +#undef min + +#define RAPIDJSON_NAMESPACE xbox::services::rapidjson +#define RAPIDJSON_NAMESPACE_BEGIN namespace xbox { namespace services { namespace rapidjson { +#define RAPIDJSON_NAMESPACE_END } } } #include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" #include "async_helpers.h" #include "xsapi_utils.h" @@ -95,7 +111,6 @@ #include "ref_counter.h" #include "internal_errors.h" #include "Logger/log.h" -#include "telemetry.h" #include "xbox_live_app_config_internal.h" #include "user.h" #include "http_call_wrapper_internal.h" diff --git a/Source/Services/Common/xbox_live_context.cpp b/Source/Services/Common/xbox_live_context.cpp index a7e278ff..b5c03b29 100644 --- a/Source/Services/Common/xbox_live_context.cpp +++ b/Source/Services/Common/xbox_live_context.cpp @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "shared_macros.h" -#include "xbox_system_factory.h" #include "xbox_live_context_internal.h" #include "presence_internal.h" @@ -25,10 +23,9 @@ using namespace xbox::services::system; ) noexcept { auto xblContext = std::shared_ptr( - new (Alloc(sizeof(XblContext))) XblContext - { - std::move(user) - } + new (Alloc(sizeof(XblContext))) XblContext{ std::move(user) }, + Deleter(), + Allocator() ); return xblContext; } @@ -58,6 +55,14 @@ HRESULT XblContext::Initialize( m_xboxLiveContextSettings = MakeShared(); std::weak_ptr thisWeakPtr = shared_from_this(); + TaskQueue globalQueue; + { + auto state = GlobalState::Get(); + if (state) + { + globalQueue = state->Queue(); + } + } { Result userResult = m_user.Copy(); @@ -140,7 +145,7 @@ HRESULT XblContext::Initialize( { Result userResult = m_user.Copy(); RETURN_HR_IF_FAILED(userResult.Hresult()); - m_multiplayerActivityService = MakeShared(userResult.ExtractPayload(), get_xsapi_singleton_async_queue(), m_xboxLiveContextSettings); + m_multiplayerActivityService = MakeShared(userResult.ExtractPayload(), globalQueue, m_xboxLiveContextSettings); } { @@ -150,7 +155,7 @@ HRESULT XblContext::Initialize( m_eventsService = MakeShared( userResult.ExtractPayload() #if XSAPI_INTERNAL_EVENTS_SERVICE - , get_xsapi_singleton_async_queue() + , globalQueue #endif ); RETURN_HR_IF_FAILED(m_eventsService->Initialize()); @@ -168,14 +173,16 @@ HRESULT XblContext::Initialize( m_notificationService = MakeShared(userResult.ExtractPayload(), m_xboxLiveContextSettings); #elif HC_PLATFORM == HC_PLATFORM_UWP m_notificationService = MakeShared(userResult.ExtractPayload(), m_xboxLiveContextSettings); - m_notificationService->RegisterWithNotificationService(AsyncContext{TaskQueue{ get_xsapi_singleton_async_queue() }}); + m_notificationService->RegisterWithNotificationService(AsyncContext{ globalQueue }); #endif #endif } +#if XSAPI_NOTIFICATION_SERVICE auto userChangedRegistrationResult = User::RegisterChangeEventHandler( [ - thisWeakPtr + thisWeakPtr, + queue{ globalQueue.DeriveWorkerQueue() } ] (UserLocalId localId, UserChangeType changeType) { @@ -184,18 +191,16 @@ HRESULT XblContext::Initialize( { if (sharedThis->m_user.LocalId() == localId.value && changeType == XalUserChange_SignedOut) { -#if XSAPI_NOTIFICATION_SERVICE - sharedThis->NotificationService()->UnregisterFromNotificationService( - AsyncContext - { - TaskQueue{ get_xsapi_singleton_async_queue() } - }); -#endif + sharedThis->NotificationService()->UnregisterFromNotificationService(AsyncContext{ queue }); } } }); - return userChangedRegistrationResult.Hresult(); + RETURN_HR_IF_FAILED(userChangedRegistrationResult.Hresult()); + m_userChangeEventToken = userChangedRegistrationResult.Payload(); +#endif + + return S_OK; } uint64_t XblContext::Xuid() const diff --git a/Source/Services/Common/xbox_live_context_api.cpp b/Source/Services/Common/xbox_live_context_api.cpp index 65cbcbe7..944a473f 100644 --- a/Source/Services/Common/xbox_live_context_api.cpp +++ b/Source/Services/Common/xbox_live_context_api.cpp @@ -89,9 +89,9 @@ void XblSetApiType( _In_ XblApiType apiType ) XBL_NOEXCEPT { - auto singleton = get_xsapi_singleton(); - if (singleton) + auto state = GlobalState::Get(); + if (state) { - singleton->m_apiType = apiType; + state->ApiType = apiType; } } diff --git a/Source/Services/Common/xbox_live_context_internal.h b/Source/Services/Common/xbox_live_context_internal.h index cccc50fa..01522a49 100644 --- a/Source/Services/Common/xbox_live_context_internal.h +++ b/Source/Services/Common/xbox_live_context_internal.h @@ -95,13 +95,6 @@ public: /// std::shared_ptr LeaderboardService(); -#if !XSAPI_NO_PPL - /// - /// A service for managing matchmaking sessions. - /// - xbox::services::matchmaking::legacy::matchmaking_service& matchmaking_service(); -#endif // !XSAPI_NO_PPL - /// /// A service for managing Rich Presence. /// diff --git a/Source/Services/Common/xbox_live_context_settings.cpp b/Source/Services/Common/xbox_live_context_settings.cpp index e5ea12b3..53c67d15 100644 --- a/Source/Services/Common/xbox_live_context_settings.cpp +++ b/Source/Services/Common/xbox_live_context_settings.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "xbox_live_context_internal.h" -#include "xbox_system_factory.h" #include "xbox_live_app_config_internal.h" #if HC_PLATFORM == HC_PLATFORM_ANDROID diff --git a/Source/Services/Common/xbox_live_global_api.cpp b/Source/Services/Common/xbox_live_global_api.cpp index 040b0570..8a7f27c5 100644 --- a/Source/Services/Common/xbox_live_global_api.cpp +++ b/Source/Services/Common/xbox_live_global_api.cpp @@ -88,10 +88,10 @@ XblGetAsyncQueue() XBL_NOEXCEPT try { XTaskQueueHandle duplicatedHandle{ nullptr }; - auto queue{ get_xsapi_singleton_async_queue() }; - if (queue) + auto state = GlobalState::Get(); + if (state && state->Queue().GetHandle()) { - XTaskQueueDuplicateHandle(queue, &duplicatedHandle); + XTaskQueueDuplicateHandle(state->Queue().GetHandle(), &duplicatedHandle); } return duplicatedHandle; } @@ -216,4 +216,5 @@ STDAPI_(void) XblRemoveServiceCallRoutedHandler( { state->RemoveServiceCallRoutedHandler(token); } -} \ No newline at end of file +} + diff --git a/Source/Services/Events/event.cpp b/Source/Services/Events/event.cpp index e19f0519..ffd327b6 100644 --- a/Source/Services/Events/event.cpp +++ b/Source/Services/Events/event.cpp @@ -91,7 +91,7 @@ Result Event::Deserialize( // tab-separated (0x0A) // xuid | event name | timestamp | dimensions json | measurements json - auto parts = utils::string_split(inputData, '\t'); + auto parts = utils::string_split_internal(inputData, '\t'); if (parts.size() < 5) { @@ -100,7 +100,7 @@ Result Event::Deserialize( auto xuid = utils::internal_string_to_uint64(parts[0]); auto& eventName = parts[1]; - auto timestamp = xbox::services::datetime::from_string(utils::string_t_from_internal_string(parts[2]), xbox::services::datetime::ISO_8601); + auto timestamp = xbox::services::datetime::from_string(parts[2], xbox::services::datetime::ISO_8601); JsonDocument dimensionsJson; dimensionsJson.Parse(parts[3].data()); @@ -158,7 +158,7 @@ xsapi_internal_string Event::Serialize() const ss << m_xuid << seperator; ss << m_eventName << seperator; - ss << utils::internal_string_from_string_t(m_timestamp.to_string(xbox::services::datetime::ISO_8601)) << seperator; + ss << m_timestamp.to_string(xbox::services::datetime::ISO_8601) << seperator; ss << JsonUtils::SerializeJson(m_dimensions) << seperator; ss << JsonUtils::SerializeJson(m_measurements); diff --git a/Source/Services/Events/event_queue.cpp b/Source/Services/Events/event_queue.cpp index 74e0cccf..10ca22bc 100644 --- a/Source/Services/Events/event_queue.cpp +++ b/Source/Services/Events/event_queue.cpp @@ -36,7 +36,7 @@ void EventQueue::Initialize() if (sharedThis && Succeeded(result)) { auto& bytes = result.Payload(); - auto fileMetadata = utils::string_split(xsapi_internal_string{ bytes.begin(), bytes.end() }, '\n'); + auto fileMetadata = utils::string_split_internal(xsapi_internal_string{ bytes.begin(), bytes.end() }, '\n'); std::lock_guard lock{ sharedThis->m_mutex }; for (auto& metadata : fileMetadata) @@ -184,7 +184,7 @@ HRESULT EventQueue::Populate() if (sharedThis && Succeeded(readResult) && sharedThis->m_mode == Mode::Normal) { auto& bytes = readResult.Payload(); - auto serializedEvents = utils::string_split(xsapi_internal_string{ bytes.begin(), bytes.end() }, '\n'); + auto serializedEvents = utils::string_split_internal(xsapi_internal_string{ bytes.begin(), bytes.end() }, '\n'); for (const auto& serializedEvent : serializedEvents) { diff --git a/Source/Services/Events/event_upload_payload.cpp b/Source/Services/Events/event_upload_payload.cpp index 39ad522e..c9d9bbd8 100644 --- a/Source/Services/Events/event_upload_payload.cpp +++ b/Source/Services/Events/event_upload_payload.cpp @@ -66,7 +66,7 @@ HRESULT EventUploadPayload::GetRequestData( EventsService::IKey(), event.FullEventName(), event.Data(), - StringFromStringT(event.Timestamp().to_string(xbox::services::datetime::date_format::ISO_8601)), + event.Timestamp().to_string(xbox::services::datetime::date_format::ISO_8601).c_str(), cll::LatencyNormal, cll::PersistenceUnspecified, cll::SensitivityUnspecified, diff --git a/Source/Services/Events/events_service_etw.cpp b/Source/Services/Events/events_service_etw.cpp index a7cf5f12..2f2d299c 100644 --- a/Source/Services/Events/events_service_etw.cpp +++ b/Source/Services/Events/events_service_etw.cpp @@ -6,8 +6,6 @@ #if XSAPI_WRL_EVENTS_SERVICE #include "events_service_etw.h" -#include "service_call_logger_data.h" -#include "service_call_logger.h" #include #include @@ -160,23 +158,6 @@ HRESULT EventsService::WriteInGameEventHelper( { try { - //Log service call - if (xbox::services::service_call_logger::get_singleton_instance()->is_enabled()) - { - std::shared_ptr tracker = service_call_logger::get_singleton_instance(); - - service_call_logger_data logData( - m_user.Xuid(), - eventName, - m_playSession, - JsonUtils::SerializeJson(dimensions), - JsonUtils::SerializeJson(measurements), - chrono_clock_t::now() - ); - - tracker->log(logData.to_string()); - } - auto fields = CreateLoggingFields(eventName, dimensions, measurements); //m_loggingChannel->loge @@ -225,8 +206,8 @@ ComPtr EventsService::CreateLoggingFields( fields->BeginStruct(HStringReference(L"properties").Get()); for (const auto& jsonPair : dimensions.GetObject()) { - std::pair pair; - pair.first = utils::string_t_from_internal_string(jsonPair.name.GetString()); + std::pair pair; + pair.first = jsonPair.name.GetString(); JsonUtils::CopyFrom(pair.second, jsonPair.value); AddValuePair(fields, pair); } @@ -239,8 +220,8 @@ ComPtr EventsService::CreateLoggingFields( fields->BeginStruct(HStringReference(L"measurements").Get()); for (const auto& jsonPair : measurements.GetObject()) { - std::pair pair; - pair.first = utils::string_t_from_internal_string(jsonPair.name.GetString()); + std::pair pair; + pair.first = jsonPair.name.GetString(); JsonUtils::CopyFrom(pair.second, jsonPair.value); AddValuePair(fields, pair); } @@ -254,21 +235,22 @@ ComPtr EventsService::CreateLoggingFields( void EventsService::AddValuePair( _Inout_ Microsoft::WRL::ComPtr fields, - _In_ const std::pair& pair + _In_ const std::pair& pair ) { // check property name. const auto& name = pair.first; THROW_CPP_INVALIDARGUMENT_IF_STRING_EMPTY(name); - regex_t regex(L"[A-Za-z]+[A-Za-z0-9]*"); + std::regex regex("[A-Za-z]+[A-Za-z0-9]*"); bool matchFound = std::regex_match(name, regex); if (!matchFound) { throw std::invalid_argument("Invalid properties or measurements name"); } - HStringReference propertyName{ name.data() }; + auto s = utility::conversions::utf8_to_utf16(name.data()); + HStringReference propertyName{ s.c_str() }; const auto& value = pair.second; switch (value.GetType()) diff --git a/Source/Services/Events/events_service_etw.h b/Source/Services/Events/events_service_etw.h index 6dd4d61d..39ede124 100644 --- a/Source/Services/Events/events_service_etw.h +++ b/Source/Services/Events/events_service_etw.h @@ -46,7 +46,7 @@ private: void AddValuePair( _Inout_ Microsoft::WRL::ComPtr fields, - _In_ const std::pair& pair + _In_ const std::pair& pair ); Microsoft::WRL::ComPtr CreateLoggingFields( diff --git a/Source/Services/Events/events_service_xsapi.cpp b/Source/Services/Events/events_service_xsapi.cpp index ed5fa77e..9c370ee4 100644 --- a/Source/Services/Events/events_service_xsapi.cpp +++ b/Source/Services/Events/events_service_xsapi.cpp @@ -5,7 +5,6 @@ #include "xsapi-c/events_c.h" #include "events_service_xsapi.h" #include "xbox_live_context_internal.h" -#include "xbox_system_factory.h" #include using namespace xbox::services; diff --git a/Source/Services/Leaderboard/leaderboard_internal.h b/Source/Services/Leaderboard/leaderboard_internal.h index 61417157..9f8097dc 100644 --- a/Source/Services/Leaderboard/leaderboard_internal.h +++ b/Source/Services/Leaderboard/leaderboard_internal.h @@ -37,7 +37,7 @@ struct LeaderboardGlobalQuery xsapi_internal_string xuid; xsapi_internal_string socialGroup; xsapi_internal_vector columns; - bool isTitleManaged; + bool isTitleManaged{ false }; }; struct LeaderboardSocialQuery @@ -47,7 +47,7 @@ struct LeaderboardSocialQuery xsapi_internal_string statName; xsapi_internal_string socialGroup; xsapi_internal_string sortOrder; - bool isTitleManaged; + bool isTitleManaged{ false }; }; class LeaderboardColumn @@ -117,7 +117,7 @@ private: xsapi_internal_string m_modernGamertagSuffix; xsapi_internal_string m_uniqueModernGamertag; uint64_t m_xuid{ 0 }; - double m_percentile{ 0 }; + double m_percentile{ 0.0 }; uint32_t m_rank{ 0 }; uint32_t m_globalRank{ 0 }; xsapi_internal_vector m_columnValues; diff --git a/Source/Services/Leaderboard/leaderboard_result.cpp b/Source/Services/Leaderboard/leaderboard_result.cpp index 1543aa88..f2c8c98d 100644 --- a/Source/Services/Leaderboard/leaderboard_result.cpp +++ b/Source/Services/Leaderboard/leaderboard_result.cpp @@ -225,11 +225,11 @@ LeaderboardResult::ParseSocialGroup(xsapi_internal_string socialGroupStr) { XblSocialGroupType socialGroup = XblSocialGroupType::None; - if (utils::str_icmp_internal(socialGroupStr, utils::internal_string_from_string_t(xbox::services::social::legacy::social_group_constants::people())) == 0) + if (utils::str_icmp_internal(socialGroupStr, xbox::services::social::legacy::social_group_constants::people()) == 0) { socialGroup = XblSocialGroupType::People; } - else if (utils::str_icmp_internal(socialGroupStr, utils::internal_string_from_string_t(xbox::services::social::legacy::social_group_constants::favorite())) == 0) + else if (utils::str_icmp_internal(socialGroupStr, xbox::services::social::legacy::social_group_constants::favorite()) == 0) { socialGroup = XblSocialGroupType::Favorites; } diff --git a/Source/Services/Leaderboard/leaderboard_service.cpp b/Source/Services/Leaderboard/leaderboard_service.cpp index a94a7249..4f7f84f3 100644 --- a/Source/Services/Leaderboard/leaderboard_service.cpp +++ b/Source/Services/Leaderboard/leaderboard_service.cpp @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "shared_macros.h" -#include "xbox_system_factory.h" -#include "xsapi_utils.h" #include "xbox_live_context_internal.h" #include "leaderboard_internal.h" @@ -59,33 +56,33 @@ CreateLeaderboardUrl( xsapi_internal_stringstream path; path << "/scids/"; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(scid), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(scid, xbox::services::uri::components::path); if (isTitleManaged) { path << "/leaderboards/stat("; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(name), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(name, xbox::services::uri::components::path); path << ")"; } else { path << "/leaderboards/"; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(name), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(name, xbox::services::uri::components::path); } - builder.set_path(utils::string_t_from_internal_string(path.str())); + builder.set_path(path.str()); if (metadata) { - builder.append_query(_T("include"), _T("valuemetadata")); + builder.append_query("include", "valuemetadata"); } if (!xuid.empty()) { - builder.append_query(_T("xuid"), utils::string_t_from_internal_string(xuid)); + builder.append_query("xuid", xuid); } if (maxItems > 0) { - builder.append_query(_T("maxItems"), maxItems); + builder.append_query("maxItems", maxItems); } if (!skipToXuid.empty()) @@ -95,27 +92,27 @@ CreateLeaderboardUrl( return xbl_result(xbl_error_code::invalid_argument, "Cannot skip to XUID and rank"); } - builder.append_query(_T("skipToUser"), utils::string_t_from_internal_string(skipToXuid)); + builder.append_query("skipToUser", skipToXuid); } else { if (!continuationToken.empty()) { - builder.append_query(_T("continuationToken"), utils::string_t_from_internal_string(continuationToken)); + builder.append_query("continuationToken", continuationToken); } else if (skipToRank > 0) { - builder.append_query(_T("skipToRank"), skipToRank); + builder.append_query("skipToRank", skipToRank); } } if (!socialGroup.empty()) { - builder.append_query(_T("view"), _T("People")); - builder.append_query(_T("viewTarget"), utils::string_t_from_internal_string(socialGroup)); + builder.append_query("view", "People"); + builder.append_query("viewTarget", socialGroup); } - return xbl_result(utils::internal_string_from_string_t(builder.to_string())); + return xbl_result(builder.to_string()); } HRESULT @@ -151,7 +148,7 @@ LeaderboardService::GetLeaderboard( if (url.err()) return utils::convert_xbox_live_error_code_to_hresult(url.err()); - std::shared_ptr query = std::make_shared(); + std::shared_ptr query = MakeShared(); query->scid = scid; query->name = name; query->xuid = xuid; @@ -267,42 +264,42 @@ CreateLeaderboardForSocialGroupUrl( xsapi_internal_stringstream path; path << "/users/xuid("; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(xuid), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(xuid, xbox::services::uri::components::path); path << ")/scids/"; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(scid), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(scid, xbox::services::uri::components::path); path << "/stats/"; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(statName), xbox::services::uri::components::path)); + path << xbox::services::uri::encode_uri(statName, xbox::services::uri::components::path); path << "/people/"; - path << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(socialGroup), xbox::services::uri::components::path)); - builder.set_path(utils::string_t_from_internal_string(path.str())); + path << xbox::services::uri::encode_uri(socialGroup, xbox::services::uri::components::path); + builder.set_path(path.str()); if (!sortOrder.empty()) { - builder.append_query(_T("sort"), utils::string_t_from_internal_string(sortOrder)); + builder.append_query("sort", sortOrder); } if (maxItems > 0) { - builder.append_query(_T("maxItems"), maxItems); + builder.append_query("maxItems", maxItems); } if (!skipToXuid.empty()) { - builder.append_query(_T("skipToUser"), utils::string_t_from_internal_string(skipToXuid)); + builder.append_query("skipToUser", skipToXuid); } else { if (!continuationToken.empty()) { - builder.append_query(_T("continuationToken"), utils::string_t_from_internal_string(continuationToken)); + builder.append_query("continuationToken", continuationToken); } else if (skipToRank > 0) { - builder.append_query(_T("skipToRank"), skipToRank); + builder.append_query("skipToRank", skipToRank); } } - return xbl_result(utils::internal_string_from_string_t(builder.to_string())); + return xbl_result(builder.to_string()); } HRESULT @@ -345,7 +342,7 @@ LeaderboardService::GetLeaderboardForSocialGroup( if (url.err()) return utils::convert_xbox_live_error_code_to_hresult(url.err()); - auto query = std::make_shared(); + auto query = MakeShared(); query->xuid = xuid; query->scid = scid; query->statName = statName; @@ -460,11 +457,11 @@ STDAPI XblLeaderboardGetLeaderboardAsync( xsapi_internal_string socialGroup(""); if (leaderboardQuery.socialGroup == XblSocialGroupType::People) { - socialGroup = utils::internal_string_from_string_t(xbox::services::social::legacy::social_group_constants::people()); + socialGroup = xbox::services::social::legacy::social_group_constants::people(); } else if (leaderboardQuery.socialGroup == XblSocialGroupType::Favorites) { - socialGroup = utils::internal_string_from_string_t(xbox::services::social::legacy::social_group_constants::favorite()); + socialGroup = xbox::services::social::legacy::social_group_constants::favorite(); } if ((leaderboardQuery.queryType == XblLeaderboardQueryType::UserStatBacked && leaderboardQuery.leaderboardName) || @@ -505,7 +502,7 @@ STDAPI XblLeaderboardGetLeaderboardAsync( { if (socialGroup.empty()) { - socialGroup = utils::internal_string_from_string_t(xbox::services::social::legacy::social_group_constants::people()); + socialGroup = xbox::services::social::legacy::social_group_constants::people(); } xsapi_internal_string statName(""); diff --git a/Source/Services/Matchmaking/matchmaking_internal.h b/Source/Services/Matchmaking/matchmaking_internal.h index eecb4bd6..f6737b90 100644 --- a/Source/Services/Matchmaking/matchmaking_internal.h +++ b/Source/Services/Matchmaking/matchmaking_internal.h @@ -198,279 +198,4 @@ private: }; -#if !defined(XBOX_LIVE_CREATORS_SDK) -#if !XSAPI_NO_PPL -namespace legacy -{ - - /// - /// Defines values used to indicate whether a match ticket is for a new - /// game session or an existing session. - /// - enum class preserve_session_mode - { - /// - /// The server returned an unrecognized response. - /// - unknown, - - /// - /// Always use an existing game session. This is for matching more players - /// for a game session that is already created or in progress. - /// - always, - - /// - /// Never use an existing game session. This is for matching players - /// for a new game session. - /// - never - }; - - /// - /// Defines values used to indicate the status of the match request. - /// - enum class ticket_status - { - /// - /// The status of the match request has not been returned by the server yet - /// or the server returned an unrecognized response. - /// - unknown, - - /// - /// Matchmaking has not found a match and the search - /// request has expired according to its give up duration. - /// - expired, - - /// - /// Matchmaking has not found a match yet and it is - /// still searching. - /// - searching, - - /// - /// Matchmaking has found a match and the ticket contains a - /// reference to the session that is to be created. - /// - found, - - /// - /// Matchmaking has been canceled for this ticket. - /// - canceled - }; - - /// - /// Represents a server response to a create match ticket request. - /// - class create_match_ticket_response - { - public: - /// - /// Internal function - /// - create_match_ticket_response(); - - /// - /// Internal function - /// - create_match_ticket_response( - XblCreateMatchTicketResponse response - ); - - /// - /// Ticket ID of a match request. - /// - string_t match_ticket_id() const; - - /// - /// Estimated wait time for a match request to be matched with other players. - /// - std::chrono::seconds estimated_wait_time() const; - - private: - XblCreateMatchTicketResponse m_createMatchTicketResponse; - }; - - /// - /// Represents a server response to a request for match ticket details. - /// - class match_ticket_details_response - { - public: - /// - /// Internal function - /// - match_ticket_details_response(); - - /// - /// Internal function - /// - match_ticket_details_response( - std::shared_ptr buffer - ); - - /// - /// Status of a match request. - /// - ticket_status match_status() const; - - /// - /// Estimated wait time for a match request to be matched with other players. - /// - std::chrono::seconds estimated_wait_time() const; - - /// - /// An enum value to specify whether the match should preserve the session on which the match has been requested. - /// - preserve_session_mode preserve_session() const; - - /// - /// The session on which the match was requested. - /// - xbox::services::multiplayer::legacy::multiplayer_session_reference ticket_session() const; - - /// - /// The session on which a match request has been found. - /// - xbox::services::multiplayer::legacy::multiplayer_session_reference target_session() const; - - /// - /// The attributes of a match request. - /// - web::json::value ticket_attributes() const; - - private: - static ticket_status convert_string_to_ticket_status(_In_ const string_t& value); - - static preserve_session_mode convert_string_to_preserve_session_mode(_In_ const string_t& value); - - std::shared_ptr m_buffer; - XblMatchTicketDetailsResponse m_matchTicketDetailsResponse; - }; - - /// - /// Represents a server response to a hopper statistics request. - /// - class hopper_statistics_response - { - public: - - /// - /// Internal function - /// - hopper_statistics_response(); - - /// - /// Internal function - /// - hopper_statistics_response( - std::shared_ptr buffer - ); - - /// - /// Name of the hopper in which a match was requested. - /// - string_t hopper_name() const; - - /// - /// Estimated wait time for a match request to be matched with other players. - /// - std::chrono::seconds estimated_wait_time() const; - - /// - /// The number of players in the hopper waiting to be matched. - /// - uint32_t players_waiting_to_match() const; - - private: - std::shared_ptr m_buffer; - XblHopperStatisticsResponse m_hopperStatisticsResponse; - }; - - /// - /// Represents the Matchmaking Service. - /// - class matchmaking_service - { - public: - /// - /// Sends a matchmaking request to the server and returns the match ticket with a ticket id. - /// - /// The multiplayer session to use for the match. - /// The service configuration ID for the match. - /// The name of the hopper. - /// The maximum time to wait for players to join the session. - /// Indicates if the session should be preserved. - /// The ticket attributes for the session. (Optional) - /// The async object for notifying when the operation is completed. With the handler, a new match ticket - /// object is returned. The match ticket object contains server returned information such as ticket id and wait - /// time, and also contains copies of the title specified data from the ticket data object. - /// Calls V103 POST /serviceconfigs/{serviceConfigId}/hoppers/{hopperName} - pplx::task> create_match_ticket( - _In_ const xbox::services::multiplayer::legacy::multiplayer_session_reference& ticketSessionReference, - _In_ const string_t& matchmakingServiceConfigurationId, - _In_ const string_t& hopperName, - _In_ const std::chrono::seconds& ticketTimeout, - _In_ preserve_session_mode preserveSession, - _In_ const web::json::value& ticketAttributesJson = web::json::value() - ); - - /// - /// Deletes a the match ticket on the server. - /// - /// The service config id that is specific for the title. - /// The name of the hopper where the match ticket is located. - /// The id of the ticket to delete on the server. - /// The async object for notifying when the operation has been completed. - /// Calls V103 DELETE /serviceconfigs/{serviceConfigId}/hoppers/{hopperName}/tickets/{ticketId} - pplx::task> delete_match_ticket( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName, - _In_ const string_t& ticketId - ); - - /// - /// Retrieves the properties of a match ticket from the server. - /// - /// The service config id that is specific for the title. - /// The name of the hopper where the match ticket is located. - /// The ticket id of the match ticket to retrieve. - /// The async object for notifying when the operation is completed. With the handler, the match - /// ticket object with the data for the ticket, including ticket id and wait time information, is returned - /// returned from the server. - /// Calls V103 GET /serviceconfigs/{serviceConfigId}/hoppers/{hopperName}/tickets/{ticketId} - pplx::task> get_match_ticket_details( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName, - _In_ const string_t& ticketId - ); - - /// - /// Gets statistics about a hopper such as how many players are in it. - /// - /// The service config id that is specific for the title. - /// The name of the hopper to query stats for. - /// The async object for notifying when the operation is completed. With the handler, an object - /// containing statistics about the hopper is returned. - /// Calls V103 GET /serviceconfigs/{serviceConfigId}/hoppers/{hopperName}/stats - pplx::task> get_hopper_statistics( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName - ); - - matchmaking_service(const matchmaking_service& other); - matchmaking_service& operator=(matchmaking_service other); - ~matchmaking_service(); - - private: - matchmaking_service(_In_ XblContextHandle contextHandle); - - XblContextHandle m_xblContext; - }; -} -#endif // !XSAPI_NO_PPL -#endif // !defined(XBOX_LIVE_CREATORS_SDK) NAMESPACE_MICROSOFT_XBOX_SERVICES_MATCHMAKING_CPP_END \ No newline at end of file diff --git a/Source/Services/Matchmaking/matchmaking_service.cpp b/Source/Services/Matchmaking/matchmaking_service.cpp index 2f7c19e5..5b7284ab 100644 --- a/Source/Services/Matchmaking/matchmaking_service.cpp +++ b/Source/Services/Matchmaking/matchmaking_service.cpp @@ -3,13 +3,11 @@ #include "pch.h" #include "shared_macros.h" -#include "xbox_system_factory.h" #include "matchmaking_internal.h" #include "xbox_live_app_config_internal.h" #include "xbox_live_context_internal.h" using namespace xbox::services; -using namespace xbox::services::legacy; NAMESPACE_MICROSOFT_XBOX_SERVICES_MATCHMAKING_CPP_BEGIN @@ -143,7 +141,7 @@ xsapi_internal_string MatchmakingService::ConvertPreserveSessionModeToString( ); } - if (errc) + if (FAILED(errc)) { return WEB_E_INVALID_JSON_STRING; } @@ -173,7 +171,7 @@ xsapi_internal_string MatchmakingService::ConvertPreserveSessionModeToString( result.estimatedWaitTime = waitTime; } - if (errc) + if (FAILED(errc)) { return WEB_E_INVALID_JSON_STRING; } @@ -236,7 +234,7 @@ xsapi_internal_string MatchmakingService::ConvertPreserveSessionModeToString( } - if (errc) + if (FAILED(errc)) { return WEB_E_INVALID_JSON_STRING; } @@ -554,330 +552,6 @@ HRESULT MatchmakingService::GetHopperStatistics( }); } -#if !defined(XBOX_LIVE_CREATORS_SDK) -#if !XSAPI_NO_PPL -namespace legacy -{ - match_ticket_details_response::match_ticket_details_response() : - m_buffer(), - m_matchTicketDetailsResponse() - { - } - - match_ticket_details_response::match_ticket_details_response(std::shared_ptr buffer) : - m_buffer(buffer), - m_matchTicketDetailsResponse(*reinterpret_cast(m_buffer.get())) - { - } - - ticket_status - match_ticket_details_response::match_status() const - { - return static_cast(m_matchTicketDetailsResponse.matchStatus); - } - - std::chrono::seconds - match_ticket_details_response::estimated_wait_time() const - { - return std::chrono::seconds(m_matchTicketDetailsResponse.estimatedWaitTime); - } - - preserve_session_mode - match_ticket_details_response::preserve_session() const - { - return static_cast(m_matchTicketDetailsResponse.preserveSession); - } - - xbox::services::multiplayer::legacy::multiplayer_session_reference - match_ticket_details_response::ticket_session() const - { - return xbox::services::multiplayer::legacy::multiplayer_session_reference( - StringTFromUtf8(m_matchTicketDetailsResponse.ticketSession.Scid), - StringTFromUtf8(m_matchTicketDetailsResponse.ticketSession.SessionTemplateName), - StringTFromUtf8(m_matchTicketDetailsResponse.ticketSession.SessionName)); - } - - xbox::services::multiplayer::legacy::multiplayer_session_reference - match_ticket_details_response::target_session() const - { - return xbox::services::multiplayer::legacy::multiplayer_session_reference( - StringTFromUtf8(m_matchTicketDetailsResponse.targetSession.Scid), - StringTFromUtf8(m_matchTicketDetailsResponse.targetSession.SessionTemplateName), - StringTFromUtf8(m_matchTicketDetailsResponse.targetSession.SessionName)); - } - - web::json::value - match_ticket_details_response::ticket_attributes() const - { - return web::json::value(StringTFromUtf8(m_matchTicketDetailsResponse.ticketAttributes)); - } - - ticket_status match_ticket_details_response::convert_string_to_ticket_status( - _In_ const string_t& value - ) - { - ticket_status ticketStatus = ticket_status::unknown; - if (!value.empty()) - { - if (Stricmp(value, _T("expired")) == 0) - { - ticketStatus = ticket_status::expired; - } - else if (Stricmp(value, _T("searching")) == 0) - { - ticketStatus = ticket_status::searching; - } - else if (Stricmp(value, _T("found")) == 0) - { - ticketStatus = ticket_status::found; - } - else if (Stricmp(value, _T("canceled")) == 0) - { - ticketStatus = ticket_status::canceled; - } - } - - return ticketStatus; - } - - preserve_session_mode match_ticket_details_response::convert_string_to_preserve_session_mode( - _In_ const string_t& value - ) - { - preserve_session_mode preserve_session_mode = preserve_session_mode::unknown; - if (!value.empty()) - { - if (Stricmp(value, _T("always")) == 0) - { - preserve_session_mode = preserve_session_mode::always; - } - else if (Stricmp(value, _T("never")) == 0) - { - preserve_session_mode = preserve_session_mode::never; - } - } - return preserve_session_mode; - } - - - hopper_statistics_response::hopper_statistics_response() : - m_buffer(), - m_hopperStatisticsResponse() - { - } - - hopper_statistics_response::hopper_statistics_response(std::shared_ptr buffer) : - m_buffer(buffer), - m_hopperStatisticsResponse(*reinterpret_cast(m_buffer.get())) - { - } - - /// - /// Name of the hopper in which a match was requested. - /// - string_t - hopper_statistics_response::hopper_name() const - { - return StringTFromUtf8(m_hopperStatisticsResponse.hopperName); - } - - /// - /// Estimated wait time for a match request to be matched with other players. - /// - std::chrono::seconds hopper_statistics_response::estimated_wait_time() const - { - return std::chrono::seconds(m_hopperStatisticsResponse.estimatedWaitTime); - } - - /// - /// The number of players in the hopper waiting to be matched. - /// - uint32_t hopper_statistics_response::players_waiting_to_match() const - { - return m_hopperStatisticsResponse.playersWaitingToMatch; - } - - create_match_ticket_response::create_match_ticket_response() : - m_createMatchTicketResponse{ } - { - } - - create_match_ticket_response::create_match_ticket_response( - XblCreateMatchTicketResponse response - ) : - m_createMatchTicketResponse(response) - { - } - - string_t - create_match_ticket_response::match_ticket_id() const - { - return StringTFromUtf8(m_createMatchTicketResponse.matchTicketId); - } - - std::chrono::seconds - create_match_ticket_response::estimated_wait_time() const - { - return std::chrono::seconds(m_createMatchTicketResponse.estimatedWaitTime); - } - - matchmaking_service::matchmaking_service(_In_ XblContextHandle contextHandle) - { - XblContextDuplicateHandle(contextHandle, &m_xblContext); - } - - matchmaking_service::matchmaking_service(const matchmaking_service& other) - { - XblContextDuplicateHandle(other.m_xblContext, &m_xblContext); - } - - matchmaking_service& matchmaking_service::operator=(matchmaking_service other) - { - std::swap(m_xblContext, other.m_xblContext); - return *this; - } - - matchmaking_service::~matchmaking_service() - { - XblContextCloseHandle(m_xblContext); - } - - pplx::task> matchmaking_service::create_match_ticket( - _In_ const xbox::services::multiplayer::legacy::multiplayer_session_reference& ticketSessionReference, - _In_ const string_t& matchmakingServiceConfigurationId, - _In_ const string_t& hopperName, - _In_ const std::chrono::seconds& ticketTimeout, - _In_ preserve_session_mode preserveSession, - _In_ const web::json::value& ticketAttributesJson - ) - { - auto xblContext = m_xblContext; - - auto asyncWrapper = new xbox::services::legacy::AsyncWrapper( - [](XAsyncBlock* async, create_match_ticket_response& result) - { - XblCreateMatchTicketResponse resultResponse; - auto hr = XblMatchmakingCreateMatchTicketResult(async, &resultResponse); - if (SUCCEEDED(hr)) - { - result = create_match_ticket_response(resultResponse); - } - return hr; - }); - - XblMultiplayerSessionReference _ticketSessionReference; - Utf8FromCharT(ticketSessionReference.service_configuration_id().data(), _ticketSessionReference.Scid, sizeof(_ticketSessionReference.Scid)); - Utf8FromCharT(ticketSessionReference.session_template_name().data(), _ticketSessionReference.SessionTemplateName, sizeof(_ticketSessionReference.SessionTemplateName)); - Utf8FromCharT(ticketSessionReference.session_name().data(), _ticketSessionReference.SessionName, sizeof(_ticketSessionReference.SessionName)); - - auto hr = XblMatchmakingCreateMatchTicketAsync( - xblContext, - _ticketSessionReference, - StringFromStringT(matchmakingServiceConfigurationId).c_str(), - StringFromStringT(hopperName).c_str(), - ticketTimeout.count(), - static_cast(preserveSession), - StringFromStringT(ticketAttributesJson.serialize()).c_str(), - &asyncWrapper->async - ); - - return asyncWrapper->Task(hr); - } - - pplx::task> matchmaking_service::delete_match_ticket( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName, - _In_ const string_t& ticketId - ) - { - auto xblContext = m_xblContext; - - auto asyncWrapper = new xbox::services::legacy::AsyncWrapper(); - auto hr = XblMatchmakingDeleteMatchTicketAsync( - xblContext, - StringFromStringT(serviceConfigurationId).c_str(), - StringFromStringT(hopperName).c_str(), - StringFromStringT(ticketId).c_str(), - &asyncWrapper->async); - - return asyncWrapper->Task(hr); - } - - pplx::task> matchmaking_service::get_match_ticket_details( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName, - _In_ const string_t& ticketId - ) - { - auto xblContext = m_xblContext; - - auto asyncWrapper = new xbox::services::legacy::AsyncWrapper( - [](XAsyncBlock* async, match_ticket_details_response& result) - { - size_t bufferSize; - auto hr = XblMatchmakingGetMatchTicketDetailsResultSize(async, &bufferSize); - if (SUCCEEDED(hr)) - { - std::shared_ptr buffer(new char[bufferSize], std::default_delete()); - XblMatchTicketDetailsResponse* resultPtr; - hr = XblMatchmakingGetMatchTicketDetailsResult(async, bufferSize, buffer.get(), &resultPtr, nullptr); - - if (SUCCEEDED(hr)) - { - result = match_ticket_details_response(buffer); - } - } - return hr; - }); - - auto hr = XblMatchmakingGetMatchTicketDetailsAsync( - xblContext, - StringFromStringT(serviceConfigurationId).c_str(), - StringFromStringT(hopperName).c_str(), - StringFromStringT(ticketId).c_str(), - &asyncWrapper->async); - - return asyncWrapper->Task(hr); - } - - pplx::task> matchmaking_service::get_hopper_statistics( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& hopperName - ) - { - auto xblContext = m_xblContext; - - auto asyncWrapper = new xbox::services::legacy::AsyncWrapper( - [](XAsyncBlock* async, hopper_statistics_response& result) - { - size_t bufferSize; - auto hr = XblMatchmakingGetHopperStatisticsResultSize(async, &bufferSize); - if (SUCCEEDED(hr)) - { - std::shared_ptr buffer(new char[bufferSize], std::default_delete()); - XblHopperStatisticsResponse* resultPtr; - hr = XblMatchmakingGetHopperStatisticsResult(async, bufferSize, buffer.get(), &resultPtr, nullptr); - - if (SUCCEEDED(hr)) - { - result = hopper_statistics_response(buffer); - } - } - return hr; - }); - - auto hr = XblMatchmakingGetHopperStatisticsAsync( - xblContext, - StringFromStringT(serviceConfigurationId).c_str(), - StringFromStringT(hopperName).c_str(), - &asyncWrapper->async); - - return asyncWrapper->Task(hr); - } -} -#endif // !XSAPI_NO_PPL -#endif // !defined(XBOX_LIVE_CREATORS_SDK) - NAMESPACE_MICROSOFT_XBOX_SERVICES_MATCHMAKING_CPP_END diff --git a/Source/Services/Multiplayer/Manager/multiplayer_client_manager.cpp b/Source/Services/Multiplayer/Manager/multiplayer_client_manager.cpp index b5c618e0..ccb03be1 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_client_manager.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_client_manager.cpp @@ -9,7 +9,11 @@ #include "multiplayer_manager_internal.h" #include "multiplayer_internal.h" #include "xbox_live_app_config_internal.h" + +#if HC_PLATFORM != HC_PLATFORM_WIN32 && !XSAPI_NO_PPL #include "xsapi-cpp/title_callable_ui.h" +#endif + #if HC_PLATFORM == HC_PLATFORM_GDK #include "XGameUI.h" @@ -97,16 +101,17 @@ MultiplayerClientManager::Initialize() { if (m_multiplayerLocalUserManager == nullptr) { - m_multiplayerLocalUserManager = std::make_shared(); + m_multiplayerLocalUserManager = MakeShared(); RegisterLocalUserManagerEvents(); } - m_latestPendingRead = std::make_shared( + m_latestPendingRead = MakeShared( + m_queue, m_lobbySessionTemplateName, m_multiplayerLocalUserManager ); - m_lastPendingRead = std::make_shared(); + m_lastPendingRead = MakeShared(m_queue); m_subscriptionsLostFired.store(false); m_latestPendingRead->SetAutoFillMembersDuringMatchmaking(m_autoFillMembers); } @@ -286,7 +291,7 @@ MultiplayerClientManager::JoinLobby( if (!invitedUserFound) { // The invited user hasn't been added. - std::shared_ptr joinLobbyEventArgs = std::make_shared(invitedXuid); + std::shared_ptr joinLobbyEventArgs = MakeShared(invitedXuid); // Since m_latestPendingRead hasn't been initialized yet, this will ensure // the event is still returned correctly through multiplayer_manager::do_work(); @@ -376,7 +381,7 @@ MultiplayerClientManager::JoinGame( initArgs.InitiatorXuids = xboxUserIds.data(); initArgs.InitiatorXuidsCount = static_cast(xboxUserIds.size()); - auto gameSession = std::make_shared( + auto gameSession = MakeShared( primaryContext->Xuid(), &gameSessionRef, &initArgs @@ -537,8 +542,8 @@ MultiplayerClientManager::InviteFriends( #elif HC_PLATFORM == HC_PLATFORM_GDK - XAsyncBlock* asyncBlock = utils::MakeAsyncBlock(); - asyncBlock->queue = get_xsapi_singleton_async_queue(); + XAsyncBlock* asyncBlock = Make(); + asyncBlock->queue = m_queue.GetHandle(); asyncBlock->context = utils::store_shared_ptr(shared_from_this()); asyncBlock->callback = [](_In_ XAsyncBlock* asyncBlock) { @@ -778,7 +783,7 @@ MultiplayerClientManager::OnMultiplayerConnectionIdChanged() if (lobbySession && lobbyClientSessionSafe.CurrentUser() && lobbyClientSessionSafe.CurrentUser()->Status == XblMultiplayerSessionMemberStatus::Active) { MultiplayerSessionMember::Get(lobbyClientSessionSafe.CurrentUser())->SetStatus(lobbyClientSessionSafe.CurrentUser()->Status); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); lobbyClient->AddToPendingQueue(pendingRequest); } @@ -788,7 +793,7 @@ MultiplayerClientManager::OnMultiplayerConnectionIdChanged() if (gameSession && gameClientSessionSafe.CurrentUser() && gameClientSessionSafe.CurrentUser()->Status == XblMultiplayerSessionMemberStatus::Active) { MultiplayerSessionMember::Get(gameClientSessionSafe.CurrentUser())->SetStatus(gameClientSessionSafe.CurrentUser()->Status); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); gameClient->AddToPendingQueue(pendingRequest); } } @@ -1030,7 +1035,7 @@ MultiplayerClientManager::HandleMemberListChanged( gameMembers.push_back(latestPendingRead->ConvertToGameMember(member)); } - std::shared_ptr memberJoinedEventArgs = std::make_shared(gameMembers); + std::shared_ptr memberJoinedEventArgs = MakeShared(gameMembers); AddToLatestPendingReadEventQueue( XblMultiplayerEventType::MemberJoined, @@ -1047,7 +1052,7 @@ MultiplayerClientManager::HandleMemberListChanged( gameMembers.push_back(latestPendingRead->ConvertToGameMember(member)); } - std::shared_ptr memberLeftEventArgs = std::make_shared( + std::shared_ptr memberLeftEventArgs = MakeShared( gameMembers ); @@ -1107,7 +1112,7 @@ MultiplayerClientManager::HandleMemberPropertiesChanged( { continue; } - std::shared_ptr memberPropertiesChangedArgs = std::make_shared( + std::shared_ptr memberPropertiesChangedArgs = MakeShared( latestPendingRead->ConvertToGameMember(member), member->CustomPropertiesJson ); @@ -1157,7 +1162,7 @@ MultiplayerClientManager::HandleSessionPropertiesChanged( } XblMultiplayerSessionReadLockGuard currentSessionSafe(currentSession); - auto gamePropertiesChangedArgs = std::make_shared( + auto gamePropertiesChangedArgs = MakeShared( currentSessionSafe.SessionProperties().SessionCustomPropertiesJson ); @@ -1186,7 +1191,7 @@ MultiplayerClientManager::HandleHostChanged( } } - std::shared_ptr hostChangedEventArgs = std::make_shared( + std::shared_ptr hostChangedEventArgs = MakeShared( hostMember ); diff --git a/Source/Services/Multiplayer/Manager/multiplayer_client_pending_reader.cpp b/Source/Services/Multiplayer/Manager/multiplayer_client_pending_reader.cpp index 542d7e7c..42c7d5cd 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_client_pending_reader.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_client_pending_reader.cpp @@ -44,13 +44,14 @@ void MultiplayerClientPendingReader::deep_copy_if_updated( } } -MultiplayerClientPendingReader::MultiplayerClientPendingReader() : +MultiplayerClientPendingReader::MultiplayerClientPendingReader(const TaskQueue& queue) : + m_queue{ queue.DeriveWorkerQueue() }, m_autoFillMembers(false) { - m_multiplayerLocalUserManager = std::make_shared(); - m_lobbyClient = std::make_shared(get_xsapi_singleton_async_queue()); - m_gameClient = std::make_shared(get_xsapi_singleton_async_queue()); - m_matchClient = std::make_shared(get_xsapi_singleton_async_queue(), m_multiplayerLocalUserManager); + m_multiplayerLocalUserManager = MakeShared(); + m_lobbyClient = MakeShared(m_queue); + m_gameClient = MakeShared(m_queue); + m_matchClient = MakeShared(m_queue, m_multiplayerLocalUserManager); } MultiplayerClientPendingReader::~MultiplayerClientPendingReader() @@ -62,15 +63,17 @@ MultiplayerClientPendingReader::~MultiplayerClientPendingReader() } MultiplayerClientPendingReader::MultiplayerClientPendingReader( + _In_ const TaskQueue& queue, _In_ const xsapi_internal_string& lobbySessionTemplateName, _In_ std::shared_ptr localUserManager ) : + m_queue{ queue.DeriveWorkerQueue() }, m_autoFillMembers(false), m_multiplayerLocalUserManager(localUserManager) { - m_lobbyClient = std::make_shared(get_xsapi_singleton_async_queue(), lobbySessionTemplateName, m_multiplayerLocalUserManager); - m_gameClient = std::make_shared(get_xsapi_singleton_async_queue(), m_multiplayerLocalUserManager); - m_matchClient = std::make_shared(get_xsapi_singleton_async_queue(), m_multiplayerLocalUserManager); + m_lobbyClient = MakeShared(m_queue, lobbySessionTemplateName, m_multiplayerLocalUserManager); + m_gameClient = MakeShared(m_queue, m_multiplayerLocalUserManager); + m_matchClient = MakeShared(m_queue, m_multiplayerLocalUserManager); m_lobbyClient->Initialize(); m_gameClient->Initialize(); } @@ -291,7 +294,7 @@ MultiplayerClientPendingReader::SetProperties( _In_opt_ context_t context ) { - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetSessionProperties(name, valueJson, context); AddToPendingQueue(sessionRef, pendingRequest); return S_OK; @@ -304,7 +307,7 @@ MultiplayerClientPendingReader::SetSynchronizedHost( _In_opt_ context_t context ) { - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetSynchronizedHostDeviceToken(hostDeviceToken, context); AddToPendingQueue(sessionRef, pendingRequest); return S_OK; @@ -318,7 +321,7 @@ MultiplayerClientPendingReader::SetSynchronizedProperties( _In_opt_ context_t context ) { - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetSynchronizedSessionProperties(name, valueJson, context); AddToPendingQueue(sessionRef, pendingRequest); return S_OK; diff --git a/Source/Services/Multiplayer/Manager/multiplayer_game_client.cpp b/Source/Services/Multiplayer/Manager/multiplayer_game_client.cpp index 9c8cff96..3f2ab0ae 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_game_client.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_game_client.cpp @@ -202,7 +202,7 @@ MultiplayerGameClient::ConvertToMultiplayerGame( gameMembers.push_back(gameMember); } - return std::make_shared( + return MakeShared( sessionToConvert, hostMember, gameMembers @@ -500,7 +500,7 @@ MultiplayerGameClient::RemoveStaleUsersFromRemoteSession() { std::weak_ptr weakSessionWriter = shared_from_this(); - auto sessionToCommit = std::make_shared(localUser->Xuid(), &gameSession->SessionReference(), nullptr); + auto sessionToCommit = MakeShared(localUser->Xuid(), &gameSession->SessionReference(), nullptr); sessionToCommit->Leave(); m_sessionWriter->WriteSession(localUser->Context(), sessionToCommit, XblMultiplayerSessionWriteMode::UpdateExisting, true, [weakSessionWriter](Result> result) @@ -716,7 +716,7 @@ HRESULT MultiplayerGameClient::JoinGameForAllLocalMembers( if (joinResult.Hresult() == HTTP_E_STATUS_NOT_FOUND && !m_handleIdToJoin.empty()) { // We tried to join an existing session but it didn't exist. Create a new game session - // from the lobby and clear the the existing handleId since it must be invalid. + // from the lobby and clear the existing handleId since it must be invalid. if (m_createGameIfFailedToJoin) { m_callback(lobbyClient->CreateGameFromLobby()); @@ -780,8 +780,16 @@ HRESULT MultiplayerGameClient::JoinGameFromLobbyHelper( // Check if the lobby has a game session associated with it to join. XblMultiplayerSessionReadLockGuard lobbySessionSafe(lobbySession); - auto lobbyProperties = ParseJson(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); - if (!lobbyProperties.has_field(utils::string_t_from_internal_string(MultiplayerLobbyClient_TransferHandlePropertyName))) + + JsonDocument jsonDoc; + jsonDoc.Parse(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); + + xsapi_internal_string transferHandle; + if (!jsonDoc.HasParseError()) + { + JsonUtils::ExtractJsonString(jsonDoc, MultiplayerLobbyClient_TransferHandlePropertyName, transferHandle, false); + } + if (transferHandle.empty()) // aka the field isn't there { return lobbyClient->CreateGameFromLobby(); } @@ -806,7 +814,7 @@ void MultiplayerGameClient::LeaveRemoteSession( _In_ bool triggerCompletionEvent ) noexcept { - auto processingRequest = std::make_shared(); + auto processingRequest = MakeShared(); m_processingQueue.push_back(processingRequest); m_sessionWriter->LeaveRemoteSession(session, diff --git a/Source/Services/Multiplayer/Manager/multiplayer_lobby_client.cpp b/Source/Services/Multiplayer/Manager/multiplayer_lobby_client.cpp index 9b8f11c9..0127eeaf 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_lobby_client.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_lobby_client.cpp @@ -240,7 +240,7 @@ MultiplayerLobbyClient::ConvertToMultiplayerLobby( gameMembers.push_back(gameMember); } - return std::make_shared( + return MakeShared( sessionToConvert, hostMember, gameMembers, @@ -333,7 +333,7 @@ MultiplayerLobbyClient::AddLocalUser( localUser = localUserResult.ExtractPayload(); } - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUser(localUser); pendingRequest->SetLobbyState(userState); if (userState == MultiplayerLocalUserLobbyState::Join) @@ -383,7 +383,7 @@ MultiplayerLobbyClient::RemoveLocalUser( auto localUser = m_multiplayerLocalUserManager->GetLocalUserHelper(user); RETURN_HR_IF_LOG_DEBUG(localUser == nullptr || localUser->Context() == nullptr, E_UNEXPECTED, "Call add_local_user() first."); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUser(localUser); pendingRequest->SetLobbyState(MultiplayerLocalUserLobbyState::Leave); AddToPendingQueue(pendingRequest); @@ -404,7 +404,7 @@ MultiplayerLobbyClient::RemoveAllLocalUsers() const auto& localUser = xboxLiveContext.second; if (localUser != nullptr) { - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUser(localUser); pendingRequest->SetLobbyState(MultiplayerLocalUserLobbyState::Leave); AddToPendingQueue(pendingRequest); @@ -427,7 +427,7 @@ MultiplayerLobbyClient::SetLocalMemberProperties( auto localUser = m_multiplayerLocalUserManager->GetLocalUserHelper(user); RETURN_HR_IF_LOG_DEBUG(localUser == nullptr || localUser->Context() == nullptr, E_UNEXPECTED, "Call add_local_user() before setting local member properties."); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUserProperties(localUser, name, valueJson, context); AddToPendingQueue(pendingRequest); @@ -447,7 +447,7 @@ MultiplayerLobbyClient::DeleteLocalMemberProperties( auto localUser = m_multiplayerLocalUserManager->GetLocalUserHelper(user); RETURN_HR_IF_LOG_DEBUG(localUser == nullptr || localUser->Context() == nullptr, E_UNEXPECTED, "Call add_local_user() before deleting local member properties."); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUserProperties(localUser, name, JsonValue(), context); AddToPendingQueue(pendingRequest); @@ -467,7 +467,7 @@ MultiplayerLobbyClient::SetLocalMemberConnectionAddress( auto localUser = m_multiplayerLocalUserManager->GetLocalUserHelper(user); RETURN_HR_IF_LOG_DEBUG(localUser == nullptr || localUser->Context() == nullptr, E_UNEXPECTED, "Call add_local_user() before setting local member connection address."); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetLocalUserConnectionAddress(localUser, address, context); AddToPendingQueue(pendingRequest); @@ -481,7 +481,7 @@ HRESULT MultiplayerLobbyClient::SetJoinability( { RETURN_HR_INVALIDARGUMENT_IF(value < XblMultiplayerJoinability::JoinableByFriends || value > XblMultiplayerJoinability::Closed); - auto pendingRequest = std::make_shared(); + auto pendingRequest = MakeShared(); pendingRequest->SetJoinability(value, context); AddToPendingQueue(pendingRequest); @@ -606,7 +606,10 @@ MultiplayerLobbyClient::DoWork() // than the join fails for the whole list of users. for (auto pendingRequest : processingQueue) { - xuidsInOrder.push_back(pendingRequest->LocalUser()->Xuid()); + if (pendingRequest->LocalUser()) + { + xuidsInOrder.push_back(pendingRequest->LocalUser()->Xuid()); + } } } @@ -1358,7 +1361,7 @@ void MultiplayerLobbyClient::AdvertiseGameSession() noexcept void CreateTransferHandle(std::shared_ptr lobbySession) noexcept { - rapidjson::Document lobbyProperties; + JsonDocument lobbyProperties; { XblMultiplayerSessionReadLockGuard lobbySessionSafe(lobbySession); lobbyProperties.Parse(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); @@ -1533,18 +1536,22 @@ MultiplayerLobbyClient::IsTransferHandleState( } XblMultiplayerSessionReadLockGuard lobbySessionSafe(lobbySession); - auto lobbyProperties = ParseJson(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); - auto propertyName = utils::string_t_from_internal_string(MultiplayerLobbyClient_TransferHandlePropertyName); - if (lobbyProperties.has_field(propertyName)) + JsonDocument jsonDoc; + jsonDoc.Parse(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); + + if (!jsonDoc.HasParseError()) { - auto transferHandleProp = utils::internal_string_from_string_t(lobbyProperties.at(propertyName).as_string()); - xsapi_internal_vector transferHandleSplit = utils::string_split(transferHandleProp, '~'); - - if (transferHandleSplit.size() > 0 && - utils::str_icmp_internal(transferHandleSplit[0], state) == 0) + xsapi_internal_string transferHandleProp; + if (SUCCEEDED(JsonUtils::ExtractJsonString(jsonDoc, MultiplayerLobbyClient_TransferHandlePropertyName, transferHandleProp, true))) { - return true; + xsapi_internal_vector transferHandleSplit = utils::string_split_internal(transferHandleProp, '~'); + + if (transferHandleSplit.size() > 0 && + utils::str_icmp_internal(transferHandleSplit[0], state) == 0) + { + return true; + } } } @@ -1561,22 +1568,26 @@ MultiplayerLobbyClient::GetTransferHandle() } XblMultiplayerSessionReadLockGuard lobbySessionSafe(lobbySession); - auto lobbyProperties = ParseJson(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); - auto propertyName = utils::string_t_from_internal_string(MultiplayerLobbyClient_TransferHandlePropertyName); + JsonDocument jsonDoc; + jsonDoc.Parse(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); - if (lobbyProperties.has_field(propertyName)) + if (!jsonDoc.HasParseError()) { - auto transferHandleProp = utils::internal_string_from_string_t(lobbyProperties.at(propertyName).as_string()); - xsapi_internal_vector transferHandleSplit = utils::string_split(transferHandleProp, '~'); - - if (transferHandleSplit.size() == 2) + xsapi_internal_string transferHandleProp; + if (SUCCEEDED(JsonUtils::ExtractJsonString(jsonDoc, MultiplayerLobbyClient_TransferHandlePropertyName, transferHandleProp, true))) { - return transferHandleSplit[1]; + xsapi_internal_vector transferHandleSplit = utils::string_split_internal(transferHandleProp, '~'); + + if (transferHandleSplit.size() == 2) + { + return transferHandleSplit[1]; + } } } return xsapi_internal_string(); } + void MultiplayerLobbyClient::LeaveRemoteSession( _In_ std::shared_ptr session @@ -1731,22 +1742,28 @@ MultiplayerLobbyClient::HandleJoinLobbyCompleted( // Join game via the transfer handle. XblMultiplayerSessionReadLockGuard lobbySessionSafe(lobbySession); - auto lobbyProperties = ParseJson(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); - if (lobbyProperties.size() > 0) + + JsonDocument lobbyProperties; + lobbyProperties.Parse(lobbySessionSafe.SessionProperties().SessionCustomPropertiesJson); + + if (!lobbyProperties.HasParseError()) { - xsapi_internal_string transferHandle; - - if (IsTransferHandleState("completed")) + if (lobbyProperties.IsObject() && lobbyProperties.MemberCount() > 0) { - transferHandle = GetTransferHandle(); - } - else - { - // No existing game session - return; - } + xsapi_internal_string transferHandle; - gameClient->JoinGameByHandle(transferHandle, false, nullptr); + if (IsTransferHandleState("completed")) + { + transferHandle = GetTransferHandle(); + } + else + { + // No existing game session + return; + } + + gameClient->JoinGameByHandle(transferHandle, false, nullptr); + } } } } @@ -1757,7 +1774,7 @@ MultiplayerLobbyClient::JoinLobbyCompleted( _In_ uint64_t invitedXboxUserId ) { - std::shared_ptr joinLobbyEventArgs = std::make_shared( + std::shared_ptr joinLobbyEventArgs = MakeShared( invitedXboxUserId ); diff --git a/Source/Services/Multiplayer/Manager/multiplayer_manager.cpp b/Source/Services/Multiplayer/Manager/multiplayer_manager.cpp index 7b24a31d..88b7322f 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_manager.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_manager.cpp @@ -49,7 +49,7 @@ void MultiplayerManager::Initialize( m_multiplayerClientManager = MakeShared(lobbySessionTemplateName, m_queue); m_multiplayerClientManager->RegisterLocalUserManagerEvents(); - m_multiplayerLobbySession = std::make_shared(m_multiplayerClientManager); + m_multiplayerLobbySession = MakeShared(m_multiplayerClientManager); } bool MultiplayerManager::IsDirty() @@ -153,7 +153,7 @@ MultiplayerManager::SetMultiplayerLobbySession( } // Don't set the lobby to null so that the title can add local users whenever it chooses. - m_multiplayerLobbySession = std::make_shared(m_multiplayerClientManager); + m_multiplayerLobbySession = MakeShared(m_multiplayerClientManager); } else { diff --git a/Source/Services/Multiplayer/Manager/multiplayer_manager_api.cpp b/Source/Services/Multiplayer/Manager/multiplayer_manager_api.cpp index 9b54a982..ea6e0a93 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_manager_api.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_manager_api.cpp @@ -281,7 +281,10 @@ STDAPI XblMultiplayerManagerLobbySessionLocalMembers( RETURN_HR_INVALIDARGUMENT_IF(localMembers == nullptr && localMembersCount > 0); for (size_t i = 0; i < localMembersVector.size(); ++i) { + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_NULL_PTR_DEREFERENCE; // null pointer deref localMembers[i] = localMembersVector[i]->GetReference(); + DISABLE_WARNING_POP; } return S_OK; }); @@ -649,7 +652,10 @@ STDAPI XblMultiplayerManagerGameSessionMembers( RETURN_HR_INVALIDARGUMENT_IF(members == nullptr && membersCount > 0); for (size_t i = 0; i < membersVector.size(); ++i) { + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_NULL_PTR_DEREFERENCE; members[i] = membersVector[i]->GetReference(); + DISABLE_WARNING_POP; } return S_OK; }); diff --git a/Source/Services/Multiplayer/Manager/multiplayer_manager_internal.h b/Source/Services/Multiplayer/Manager/multiplayer_manager_internal.h index 1c34c803..3ff1edd0 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_manager_internal.h +++ b/Source/Services/Multiplayer/Manager/multiplayer_manager_internal.h @@ -311,9 +311,9 @@ private: xsapi_internal_vector> m_localMembers; xsapi_internal_string m_customPropertiesJson; - XblMultiplayerSessionConstants m_sessionConstants; + XblMultiplayerSessionConstants m_sessionConstants{}; xsapi_internal_vector m_initiatorXuids; - XblMultiplayerMemberInitialization m_memberInitialization; + XblMultiplayerMemberInitialization m_memberInitialization{}; xsapi_internal_string m_constantsCustomJson; xsapi_internal_string m_constantsCloudComputePackageJson; xsapi_internal_string m_constantsMeasurementServerAddressesJson; @@ -1133,9 +1133,10 @@ private: class MultiplayerClientPendingReader : public std::enable_shared_from_this { public: - MultiplayerClientPendingReader(); + MultiplayerClientPendingReader(const TaskQueue& queue); ~MultiplayerClientPendingReader(); MultiplayerClientPendingReader( + _In_ const TaskQueue& queue, _In_ const xsapi_internal_string& lobbySessionTemplateName, _In_ std::shared_ptr localUserManager ); @@ -1215,6 +1216,7 @@ private: static bool IsLocal(_In_ uint64_t xuid, _In_ const xsapi_internal_map>& xboxLiveContextMap); + TaskQueue m_queue; bool m_autoFillMembers; MultiplayerEventQueue m_multiplayerEventQueue; mutable std::mutex m_clientRequestLock; @@ -1544,12 +1546,12 @@ private: std::mutex m_synchronizeWriteWithTapLock; std::atomic m_subscriptionsLostFired; - bool m_autoFillMembers; + bool m_autoFillMembers{ false }; xsapi_internal_string m_lobbySessionTemplateName; - XblFunctionContext m_sessionChangedContext; - XblFunctionContext m_connectionIdChangedContext; - XblFunctionContext m_subscriptionLostContext; - XblFunctionContext m_rtaResyncContext; + XblFunctionContext m_sessionChangedContext{ 0 }; + XblFunctionContext m_connectionIdChangedContext{ 0 }; + XblFunctionContext m_subscriptionLostContext{ 0 }; + XblFunctionContext m_rtaResyncContext{ 0 }; MultiplayerEventQueue m_multiplayerEventQueue; std::shared_ptr m_primaryXboxLiveContext; diff --git a/Source/Services/Multiplayer/Manager/multiplayer_manager_utils.cpp b/Source/Services/Multiplayer/Manager/multiplayer_manager_utils.cpp index 6dfe55b4..b7954759 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_manager_utils.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_manager_utils.cpp @@ -65,12 +65,12 @@ XblMultiplayerJoinability MultiplayerManagerUtils::GetJoinability( ) { xsapi_internal_string joinableStr; - auto customPropertiesjson = ParseJson(sessionProperties.SessionCustomPropertiesJson); - auto propertyName = utils::string_t_from_internal_string(MultiplayerLobbyClient_JoinabilityPropertyName); + JsonDocument jsonDoc; + jsonDoc.Parse(sessionProperties.SessionCustomPropertiesJson); - if (customPropertiesjson.has_field(propertyName)) + if (!jsonDoc.HasParseError()) { - joinableStr = utils::internal_string_from_string_t(customPropertiesjson.at(propertyName).as_string()); + JsonUtils::ExtractJsonString(jsonDoc, MultiplayerLobbyClient_JoinabilityPropertyName, joinableStr, false); } return ConvertStringToJoinability(joinableStr); diff --git a/Source/Services/Multiplayer/Manager/multiplayer_match_client.cpp b/Source/Services/Multiplayer/Manager/multiplayer_match_client.cpp index 590b0eed..d6b8f300 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_match_client.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_match_client.cpp @@ -18,7 +18,7 @@ using namespace Windows::Xbox::Networking; NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_BEGIN MultiplayerMatchClient::MultiplayerMatchClient( - const TaskQueue& queue, + _In_ const TaskQueue& queue, _In_ std::shared_ptr localUserManager ) noexcept : m_queue{ queue.DeriveWorkerQueue() }, @@ -164,14 +164,14 @@ MultiplayerMatchClient::CheckNextTimer() void MultiplayerMatchClient::HandleQosMeasurements() { - std::shared_ptr performQosEventArgs = std::make_shared(); + std::shared_ptr performQosEventArgs = MakeShared(); XblMultiplayerSessionReadLockGuard sessionSafe(Session()); for (const auto& member : sessionSafe.Members()) { if (!member.IsCurrentUser) { - std::vector base64ConnectionAddress(xbox::services::convert::from_base64(utils::string_t_from_internal_string(member.SecureDeviceBaseAddress64))); + std::vector base64ConnectionAddress(xbox::services::convert::from_base64(member.SecureDeviceBaseAddress64)); const xsapi_internal_string& secureDeviceAddress = xsapi_internal_string(base64ConnectionAddress.begin(), base64ConnectionAddress.end()); if (!secureDeviceAddress.empty()) { @@ -215,7 +215,7 @@ MultiplayerMatchClient::HandleFindMatchCompleted( failure = matchSessionSafe.CurrentUser()->InitializationFailureCause; } - std::shared_ptr findMatchEventArgs = std::make_shared( + std::shared_ptr findMatchEventArgs = MakeShared( m_matchStatus, failure ); @@ -564,7 +564,7 @@ void MultiplayerMatchClient::HandleMatchFound( m_matchStatus = XblMultiplayerMatchStatus::Found; auto& targetSessionRef = currentSession->MatchmakingServer()->TargetSessionRef; - auto targetGameSession = std::make_shared( + auto targetGameSession = MakeShared( primaryXboxLiveContext->Xuid(), &targetSessionRef, nullptr diff --git a/Source/Services/Multiplayer/Manager/multiplayer_session_writer.cpp b/Source/Services/Multiplayer/Manager/multiplayer_session_writer.cpp index 5b05c831..c38202d1 100644 --- a/Source/Services/Multiplayer/Manager/multiplayer_session_writer.cpp +++ b/Source/Services/Multiplayer/Manager/multiplayer_session_writer.cpp @@ -626,7 +626,7 @@ MultiplayerSessionWriter::HandleEvents( eventQueue.AddEvent( XblMultiplayerEventType::SynchronizedHostWriteCompleted, sessionType, - std::make_shared(), + MakeShared(), error, request->Context() ); diff --git a/Source/Services/Multiplayer/multiplayer_activity_handle_post_request.cpp b/Source/Services/Multiplayer/multiplayer_activity_handle_post_request.cpp index 7d584b6c..37fe8286 100644 --- a/Source/Services/Multiplayer/multiplayer_activity_handle_post_request.cpp +++ b/Source/Services/Multiplayer/multiplayer_activity_handle_post_request.cpp @@ -21,7 +21,7 @@ MultiplayerActivityHandlePostRequest::SessionReference() const } void -MultiplayerActivityHandlePostRequest::Serialize(_Out_ JsonValue& json, JsonDocument::AllocatorType& allocator) const +MultiplayerActivityHandlePostRequest::Serialize(_Out_ JsonValue& json, _In_ JsonDocument::AllocatorType& allocator) const { json.SetObject(); diff --git a/Source/Services/Multiplayer/multiplayer_activity_query_post_request.cpp b/Source/Services/Multiplayer/multiplayer_activity_query_post_request.cpp index dc376feb..a1dfd3f5 100644 --- a/Source/Services/Multiplayer/multiplayer_activity_query_post_request.cpp +++ b/Source/Services/Multiplayer/multiplayer_activity_query_post_request.cpp @@ -54,7 +54,7 @@ MultiplayerActivityQueryPostRequest::SocialGroupXuid() const } void -MultiplayerActivityQueryPostRequest::Serialize(_Out_ JsonValue& json, JsonDocument::AllocatorType& allocator) +MultiplayerActivityQueryPostRequest::Serialize(_Out_ JsonValue& json, _In_ JsonDocument::AllocatorType& allocator) { XSAPI_ASSERT(m_socialGroup.empty() || m_xuids.empty()); XSAPI_ASSERT(!m_socialGroup.empty() || !m_xuids.empty()); diff --git a/Source/Services/Multiplayer/multiplayer_api.cpp b/Source/Services/Multiplayer/multiplayer_api.cpp index 53fc1678..37c90b28 100644 --- a/Source/Services/Multiplayer/multiplayer_api.cpp +++ b/Source/Services/Multiplayer/multiplayer_api.cpp @@ -198,6 +198,31 @@ STDAPI XblMultiplayerCreateSearchHandleAsync( RETURN_HR_INVALIDARGUMENT_IF(numberAttributesCount > 0 && numberAttributes == nullptr); RETURN_HR_INVALIDARGUMENT_IF(stringAttributesCount > 0 && stringAttributes == nullptr); + //ensure all attributes are properly terminated, otherwise we'll write a property + //longer than is allowed into the json, which will crash eventually on deserialization + if (tagsCount > 0) + { + for (size_t i = 0; i < tagsCount; i++) + { + RETURN_HR_INVALIDARGUMENT_IF(utils::EnsureLessThanMaxLength(tags[i].value, XBL_MULTIPLAYER_SEARCH_HANDLE_MAX_FIELD_LENGTH) == false); + } + } + if (numberAttributesCount > 0) + { + for (size_t i = 0; i < numberAttributesCount; i++) + { + RETURN_HR_INVALIDARGUMENT_IF(utils::EnsureLessThanMaxLength(numberAttributes[i].name, XBL_MULTIPLAYER_SEARCH_HANDLE_MAX_FIELD_LENGTH) == false); + } + } + if (stringAttributesCount > 0) + { + for (size_t i = 0; i < stringAttributesCount; i++) + { + RETURN_HR_INVALIDARGUMENT_IF(utils::EnsureLessThanMaxLength(stringAttributes[i].name, XBL_MULTIPLAYER_SEARCH_HANDLE_MAX_FIELD_LENGTH) == false); + RETURN_HR_INVALIDARGUMENT_IF(utils::EnsureLessThanMaxLength(stringAttributes[i].value, XBL_MULTIPLAYER_SEARCH_HANDLE_MAX_FIELD_LENGTH) == false); + } + } + MultiplayerSearchHandleRequest request{ *sessionRef }; if (tagsCount > 0) { diff --git a/Source/Services/Multiplayer/multiplayer_internal.h b/Source/Services/Multiplayer/multiplayer_internal.h index 2937649a..8d77019d 100644 --- a/Source/Services/Multiplayer/multiplayer_internal.h +++ b/Source/Services/Multiplayer/multiplayer_internal.h @@ -117,7 +117,7 @@ private: xsapi_internal_vector m_encounters; // TODO these never get deserialized xsapi_internal_vector m_membersInGroupIds; - XblMultiplayerSessionChangeTypes m_subscribedChangeTypes; + XblMultiplayerSessionChangeTypes m_subscribedChangeTypes{ XblMultiplayerSessionChangeTypes::None }; xsapi_internal_string m_matchmakingResultServerMeasurementsJson; xsapi_internal_string m_serverMeasurementsJson; xsapi_internal_string m_qosMeasurementsJson; @@ -572,78 +572,6 @@ private: Vector m_values{}; }; -#if !XSAPI_NO_PPL -namespace legacy -{ - /// - /// Represents a reference to a multiplayer session. - /// - class multiplayer_session_reference - { - public: - /// - /// Constructs a null MultiplayerSession object. - /// - multiplayer_session_reference(); - - /// - /// Constructs the MultiplayerSession object with data about the session. - /// - /// A service configuration ID appropriate for the title. - /// The name of the template for the session to be based on. - /// A unique name for the session. - multiplayer_session_reference( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& sessionTemplateName, - _In_ const string_t& sessionName - ); - - /// - /// The service configuration ID specific to the title. - /// - string_t service_configuration_id() const; - - /// - /// The name of the template for the session. - /// - string_t session_template_name() const; - - /// - /// The name of the session. - /// - string_t session_name() const; - - /// - /// Whether this object has been properly constructed - /// - bool is_null() const; - - /// - /// Returns a URI path representation of the session reference. - /// - string_t to_uri_path() const; - - /// - /// Returns the session reference parsed from URI. - /// - static multiplayer_session_reference parse_from_uri_path(_In_ const string_t& path); - - /// - /// Internal function - /// - multiplayer_session_reference(_In_ const XblMultiplayerSessionReference& reference); - - private: - mutable XblMultiplayerSessionReference m_reference; - //friend class multiplayer_session; - //friend class multiplayer_service; - //friend class multiplayer_search_handle_request; - //friend class social::reputation_service; - }; - -} -#endif - NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_CPP_END struct XblMultiplayerSession : public xbox::services::RefCounter, public std::enable_shared_from_this diff --git a/Source/Services/Multiplayer/multiplayer_service.cpp b/Source/Services/Multiplayer/multiplayer_service.cpp index 48f99839..d9d285a8 100644 --- a/Source/Services/Multiplayer/multiplayer_service.cpp +++ b/Source/Services/Multiplayer/multiplayer_service.cpp @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "xbox_system_factory.h" #include "multiplayer_internal.h" #include "xbox_live_context_internal.h" #include "real_time_activity_manager.h" @@ -260,7 +259,7 @@ String SessionQuery::PathAndQuery() const noexcept { Stringstream param; param << "xuid="; - param << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::uint64_to_string_t(XuidFilters[0]))); + param << xbox::services::uri::encode_uri(utils::uint64_to_internal_string(XuidFilters[0])); params.push_back(param.str()); } @@ -268,7 +267,7 @@ String SessionQuery::PathAndQuery() const noexcept { Stringstream param; param << "keyword="; - param << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_utf8(KeywordFilter))); + param << xbox::services::uri::encode_uri(KeywordFilter); params.push_back(param.str()); } @@ -276,7 +275,7 @@ String SessionQuery::PathAndQuery() const noexcept { Stringstream param; param << "visibility="; - param << utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(Serializers::StringFromMultiplayerSessionVisibility(VisibilityFilter)))); + param << xbox::services::uri::encode_uri(Serializers::StringFromMultiplayerSessionVisibility(VisibilityFilter)); params.push_back(param.str()); } @@ -486,7 +485,7 @@ HRESULT MultiplayerService::SetTransferHandle( auto result = Serializers::DeserializeMultiplayerInvite(httpResult.Payload()->GetResponseBodyJson()); auto multiplayerInvite = result.Payload(); - if (result.Hresult()) + if (Failed(result)) { return async.Complete(result.Hresult()); } @@ -648,7 +647,7 @@ HRESULT MultiplayerService::DeleteSearchHandle( m_xboxLiveContextSettings, "DELETE", XblHttpCall::BuildUrl("sessiondirectory", handleStr), - xbox_live_api::set_activity + xbox_live_api::delete_search_handle )); RETURN_HR_IF_FAILED(httpCall->SetXblServiceContractVersion(MULTIPLAYER_SERVICE_CONTRACT_VERSION)); @@ -1077,7 +1076,8 @@ HRESULT MultiplayerService::WriteSessionUsingSubpath( } else if (statusCode == 204) { - return async.Complete({ xbl_error_code::no_error }); + // Consistent with XDK behavior, return success on 204 when writing session + return async.Complete(S_OK); } auto responseJson = httpResult.Payload()->GetResponseBodyJson(); @@ -1110,7 +1110,7 @@ HRESULT MultiplayerService::WriteSessionUsingSubpath( httpResult.Payload()->GetResponseBodyJson() ); - if (session->DeserializationError() && SUCCEEDED(hr)) + if (FAILED(session->DeserializationError()) && SUCCEEDED(hr)) { // WriteSession failed due to deserialization error hr = session->DeserializationError(); @@ -1316,7 +1316,7 @@ void MultiplayerService::RemoveMultiplayerSubscriptionLostHandler( } XblFunctionContext MultiplayerService::AddMultiplayerConnectionIdChangedHandler( - MultiplayerSubscription::ConnectionIdChangedHandler handler + _In_ MultiplayerSubscription::ConnectionIdChangedHandler handler ) noexcept { std::lock_guard lock{ m_mutexMultiplayerService }; diff --git a/Source/Services/Multiplayer/multiplayer_session.cpp b/Source/Services/Multiplayer/multiplayer_session.cpp index 2392c55a..d1a43bbd 100644 --- a/Source/Services/Multiplayer/multiplayer_session.cpp +++ b/Source/Services/Multiplayer/multiplayer_session.cpp @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" - -#include "xbox_system_factory.h" -#include "xsapi_utils.h" #include "multiplayer_internal.h" using namespace xbox::services; @@ -61,7 +58,7 @@ XblMultiplayerSession::XblMultiplayerSession( m_writeConstants(false), m_memberRequestIndex(0) { - auto sessionDatetime = xbox::services::datetime::from_string(utils::string_t_from_internal_string(responseDate), xbox::services::datetime::date_format::RFC_1123); + auto sessionDatetime = xbox::services::datetime::from_string(responseDate, xbox::services::datetime::date_format::RFC_1123); m_sessionRetrievedTime = utils::time_t_from_datetime(sessionDatetime); Initialize(); Deserialize(json); @@ -1466,7 +1463,7 @@ HRESULT XblMultiplayerSession::Deserialize( { return Result(WEB_E_INVALID_JSON_STRING); } - XblDeviceToken token; + XblDeviceToken token{}; utils::strcpy(token.Value, sizeof(token.Value), json.GetString()); return Result(token); }, json, "hostCandidates", m_hostCandidates, false)); @@ -1991,21 +1988,32 @@ bool XblMultiplayerSession::HasSessionPropertyChanged( return false; } - auto propertyName = utils::string_t_from_internal_string(_propertyName); + auto propertyName = _propertyName; - auto customProp1 = ParseJson(session1->m_sessionCustomPropertiesJson.data()); - auto customProp2 = ParseJson(session2->m_sessionCustomPropertiesJson.data()); - if ((customProp1.has_field(propertyName) && !customProp2.has_field(propertyName)) || - (!customProp1.has_field(propertyName) && customProp2.has_field(propertyName))) - { - return true; - } + JsonDocument customProp1; + JsonDocument customProp2; + customProp1.Parse(session1->m_sessionCustomPropertiesJson.data()); + customProp2.Parse(session2->m_sessionCustomPropertiesJson.data()); - if (customProp1.has_field(propertyName) && customProp2.has_field(propertyName)) + if (!customProp1.HasParseError() && + !customProp2.HasParseError()) { - const auto& prop1 = customProp1.at(propertyName).as_string(); - const auto& prop2 = customProp2.at(propertyName).as_string(); - return utils::str_icmp(prop1, prop2) != 0; + xsapi_internal_string prop1; + xsapi_internal_string prop2; + + bool isInProp1 = SUCCEEDED(JsonUtils::ExtractJsonString(customProp1, propertyName, prop1, true)); + bool isInProp2 = SUCCEEDED(JsonUtils::ExtractJsonString(customProp2, propertyName, prop2, true)); + + if ((isInProp1 && !isInProp2) || + (!isInProp1 && isInProp2)) + { + return true; + } + + if (isInProp1 && isInProp2) + { + return utils::str_icmp(prop1.c_str(), prop2.c_str()) != 0; + } } return false; @@ -3113,7 +3121,7 @@ STDAPI XblMultiplayerSessionCurrentUserSetSecureDeviceAddressBase64( #if HC_PLATFORM != HC_PLATFORM_XDK && HC_PLATFORM != HC_PLATFORM_UWP STDAPI XblFormatSecureDeviceAddress( _In_ const char* deviceId, - _Out_ XblFormattedSecureDeviceAddress* address + _Inout_ XblFormattedSecureDeviceAddress* address ) XBL_NOEXCEPT { RETURN_HR_INVALIDARGUMENT_IF_NULL(address); diff --git a/Source/Services/Multiplayer/multiplayer_session_member.cpp b/Source/Services/Multiplayer/multiplayer_session_member.cpp index 5395ec8d..ca0964a9 100644 --- a/Source/Services/Multiplayer/multiplayer_session_member.cpp +++ b/Source/Services/Multiplayer/multiplayer_session_member.cpp @@ -705,8 +705,10 @@ void MultiplayerSessionMember::SetExternalMemberPointer(XblMultiplayerSessionMem auto internalMember = Get(&member); internalMember->m_member = &member; + member.InitialTeam = internalMember->m_initialTeam.empty() ? nullptr : internalMember->m_initialTeam.data(); member.CustomConstantsJson = internalMember->m_customConstantsJson.empty() ? nullptr :internalMember->m_customConstantsJson.data(); member.SecureDeviceBaseAddress64 = internalMember->m_secureDeviceAddressBase64.empty() ? nullptr : internalMember->m_secureDeviceAddressBase64.data(); + member.Roles = internalMember->m_roles.empty() ? nullptr : internalMember->m_roles.data(); member.CustomPropertiesJson = internalMember->m_customPropertiesString.empty() ? nullptr : internalMember->m_customPropertiesString.data(); member.MatchmakingResultServerMeasurementsJson = internalMember->m_matchmakingResultServerMeasurementsJson.empty() ? nullptr : internalMember->m_matchmakingResultServerMeasurementsJson.data(); member.ServerMeasurementsJson = internalMember->m_serverMeasurementsJson.empty() ? nullptr : internalMember->m_serverMeasurementsJson.data(); @@ -714,7 +716,6 @@ void MultiplayerSessionMember::SetExternalMemberPointer(XblMultiplayerSessionMem member.QosMeasurementsJson = internalMember->m_qosMeasurementsJson.empty() ? nullptr : internalMember->m_qosMeasurementsJson.data(); member.Groups = internalMember->m_groups.empty() ? nullptr : internalMember->m_groups.data(); member.Encounters = internalMember->m_encounters.empty() ? nullptr : internalMember->m_encounters.data(); - member.Roles = internalMember->m_roles.empty() ? nullptr : internalMember->m_roles.data(); } NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_CPP_END diff --git a/Source/Services/Multiplayer/multiplayer_session_reference.cpp b/Source/Services/Multiplayer/multiplayer_session_reference.cpp index 966791a0..05ec047b 100644 --- a/Source/Services/Multiplayer/multiplayer_session_reference.cpp +++ b/Source/Services/Multiplayer/multiplayer_session_reference.cpp @@ -19,7 +19,7 @@ STDAPI XblMultiplayerSessionReferenceParseFromUriPath( // / 0 / 1 / 2 / 3 / 4 / 5 // /serviceconfigs/{scid}/sessiontemplates/{session-template-name}/sessions/{session-name} - xsapi_internal_vector pathComponents = utils::string_split(xsapi_internal_string(path), '/'); + xsapi_internal_vector pathComponents = utils::string_split_internal(xsapi_internal_string(path), '/'); if (pathComponents.size() < 6) { return E_INVALIDARG; @@ -103,68 +103,4 @@ bool operator==(const XblMultiplayerSessionReference& lhs, const XblMultiplayerS utils::str_icmp(lhs.SessionTemplateName, rhs.SessionTemplateName) == 0; } -#if !XSAPI_NO_PPL -namespace legacy -{ - multiplayer_session_reference::multiplayer_session_reference() : m_reference{} - { - } - - multiplayer_session_reference::multiplayer_session_reference( - _In_ const string_t& serviceConfigurationId, - _In_ const string_t& sessionTemplateName, - _In_ const string_t& sessionName - ) - { - Utf8FromCharT(serviceConfigurationId.data(), m_reference.Scid, sizeof(m_reference.Scid)); - Utf8FromCharT(sessionTemplateName.data(), m_reference.SessionTemplateName, sizeof(m_reference.SessionTemplateName)); - Utf8FromCharT(sessionName.data(), m_reference.SessionName, sizeof(m_reference.SessionName)); - } - - multiplayer_session_reference::multiplayer_session_reference( - _In_ const XblMultiplayerSessionReference& reference - ) - : m_reference(reference) - { - } - - string_t multiplayer_session_reference::service_configuration_id() const - { - return StringTFromUtf8(m_reference.Scid); - } - - string_t multiplayer_session_reference::session_template_name() const - { - return StringTFromUtf8(m_reference.SessionTemplateName); - } - - string_t multiplayer_session_reference::session_name() const - { - return StringTFromUtf8(m_reference.SessionName); - } - - bool multiplayer_session_reference::is_null() const - { - return m_reference.Scid[0] == 0 || - m_reference.SessionName[0] == 0 || - m_reference.SessionTemplateName[0] == 0; - } - - string_t multiplayer_session_reference::to_uri_path() const - { - XblMultiplayerSessionReferenceUri uri{}; - XblMultiplayerSessionReferenceToUriPath(&m_reference, &uri); - - return StringTFromUtf8(uri.value); - } - - multiplayer_session_reference multiplayer_session_reference::parse_from_uri_path(_In_ const string_t& path) - { - XblMultiplayerSessionReference reference; - XblMultiplayerSessionReferenceParseFromUriPath(StringFromStringT(path).data(), &reference); - return multiplayer_session_reference(reference); - } -} -#endif - NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_CPP_END \ No newline at end of file diff --git a/Source/Services/Multiplayer/multiplayer_subscription.cpp b/Source/Services/Multiplayer/multiplayer_subscription.cpp index 0974764b..f825a227 100644 --- a/Source/Services/Multiplayer/multiplayer_subscription.cpp +++ b/Source/Services/Multiplayer/multiplayer_subscription.cpp @@ -95,7 +95,7 @@ void MultiplayerSubscription::OnEvent( { String resourceName; JsonUtils::ExtractJsonString(tapValue, "resource", resourceName, true); - Vector nameComponents = utils::string_split(resourceName, '~'); + Vector nameComponents = utils::string_split_internal(resourceName, '~'); if (nameComponents.size() != 3) { diff --git a/Source/Services/MultiplayerActivity/multiplayer_activity_service.cpp b/Source/Services/MultiplayerActivity/multiplayer_activity_service.cpp index 83a0a090..51bcabfd 100644 --- a/Source/Services/MultiplayerActivity/multiplayer_activity_service.cpp +++ b/Source/Services/MultiplayerActivity/multiplayer_activity_service.cpp @@ -244,7 +244,7 @@ HRESULT MultiplayerActivityService::SetActivity( m_xboxLiveContextSettings, "PUT", XblHttpCall::BuildUrl(MPA_SERVICE_NAME, path.str()), - xbox_live_api::update_activity + xbox_live_api::set_activity )); RETURN_HR_IF_FAILED(httpCall->SetRequestBody(requestBody)); diff --git a/Source/Services/Notification/RTA/achievement_unlock_subscription.cpp b/Source/Services/Notification/RTA/achievement_unlock_subscription.cpp index c85e5776..d03b153d 100644 --- a/Source/Services/Notification/RTA/achievement_unlock_subscription.cpp +++ b/Source/Services/Notification/RTA/achievement_unlock_subscription.cpp @@ -70,7 +70,7 @@ AchievementUnlockSubscription::OnResync() noexcept LOGS_ERROR << __FUNCTION__ << ": Achievement Unlock event may have been discarded by RTA service"; } -AchievementUnlockEvent::AchievementUnlockEvent( AchievementUnlockEvent&& event ) : +AchievementUnlockEvent::AchievementUnlockEvent( AchievementUnlockEvent&& event ) noexcept: m_achievementId(std::move(event.m_achievementId)), m_achievementName(std::move(event.m_achievementName)), m_achievementDescription(std::move(event.m_achievementDescription)), @@ -126,7 +126,7 @@ Result AchievementUnlockEvent::Deserialize( _In_ const J RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "achievementId", result.m_achievementId, true)); - RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "achievementDescription", result.m_achievementDescription, true)); + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "achievementDescription", result.m_achievementDescription, false)); RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "achievementName", result.m_achievementName, true)); @@ -136,15 +136,16 @@ Result AchievementUnlockEvent::Deserialize( _In_ const J RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonUInt64( json, "gamerscore", result.gamerscore, true)); - RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonInt(json, "xuid", result.xboxUserId, true)); - + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonXuid(json, "xuid", result.xboxUserId, true)); + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "extendedInfoUrl", result.m_deepLink, true)); - RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonDouble( json, "rarityPercentage", rarityPercentage, true)); - - RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString( json, "rarityCategory", rarityCategory, true)); - - RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonTimeT( json, "unlockTime", result.timeUnlocked)); + // RarityPercentage and rarityCategory are only in payload version 2 so make them optional + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonDouble(json, "rarityPercentage", rarityPercentage, false)); + + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "rarityCategory", rarityCategory, false)); + + RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonTimeT(json, "unlockTime", result.timeUnlocked)); result.titleId = static_cast(titleId); result.rarityPercentage = static_cast(rarityPercentage); @@ -153,7 +154,10 @@ Result AchievementUnlockEvent::Deserialize( _In_ const J // strings for the C API result.achievementId = result.m_achievementId.c_str(); result.achievementName = result.m_achievementName.c_str(); - result.achievementDescription = result.m_achievementDescription.c_str(); + if (!result.m_achievementDescription.empty()) + { + result.achievementDescription = result.m_achievementDescription.c_str(); + } result.achievementIcon = result.m_achievementIconUri.c_str(); result.m_deepLink = result.m_deepLink.c_str(); diff --git a/Source/Services/Notification/RTA/achievement_unlock_subscription.h b/Source/Services/Notification/RTA/achievement_unlock_subscription.h index 2151a944..6cb8da65 100644 --- a/Source/Services/Notification/RTA/achievement_unlock_subscription.h +++ b/Source/Services/Notification/RTA/achievement_unlock_subscription.h @@ -14,10 +14,10 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN public: AchievementUnlockEvent() = default; - AchievementUnlockEvent( AchievementUnlockEvent&& event); + AchievementUnlockEvent( AchievementUnlockEvent&& event) noexcept; AchievementUnlockEvent(const AchievementUnlockEvent& event); - static Result Deserialize( const JsonValue& json ) noexcept; + static Result Deserialize(_In_ const JsonValue& json ) noexcept; private: diff --git a/Source/Services/Notification/RTA/game_invite_subscription.cpp b/Source/Services/Notification/RTA/game_invite_subscription.cpp index d1f5d968..1d3d945f 100644 --- a/Source/Services/Notification/RTA/game_invite_subscription.cpp +++ b/Source/Services/Notification/RTA/game_invite_subscription.cpp @@ -51,7 +51,7 @@ size_t GameInviteSubscription::RemoveHandler( std::lock_guard lock{ m_mutex }; m_mpaInviteHandlers.erase(token); m_mpsdInviteHandlers.erase(token); - return m_mpaInviteHandlers.size() + m_mpaInviteHandlers.size(); + return m_mpaInviteHandlers.size() + m_mpsdInviteHandlers.size(); } void GameInviteSubscription::OnEvent( diff --git a/Source/Services/Notification/UWP/notification_service_uwp.cpp b/Source/Services/Notification/UWP/notification_service_uwp.cpp index 99572a6f..c1c6f4f7 100644 --- a/Source/Services/Notification/UWP/notification_service_uwp.cpp +++ b/Source/Services/Notification/UWP/notification_service_uwp.cpp @@ -149,15 +149,6 @@ void UWPNotificationService::OnPushNotificationReceived( { LOGS_INFO << "Received WNS notification, type: " << notificationTypeString << ", xuid: " << xuid; - auto xsapiSingleton = get_xsapi_singleton(); - if (!xsapiSingleton) - { - - LOGS_ERROR << "Receiving WNS notification error: xsapi_singleton is null."; - } - - xsapiSingleton->m_xboxServiceSettingsSingleton->_Raise_wns_event(utils::string_t_from_internal_string(xuid), utils::string_t_from_internal_string(notificationTypeString), content); - if (utils::str_icmp(notificationTypeString.c_str(), "spop") == 0) { User::SetTokenExpired(utils::internal_string_to_uint64(xuid)); diff --git a/Source/Services/Notification/notification_internal.h b/Source/Services/Notification/notification_internal.h index e17bd813..0733598b 100644 --- a/Source/Services/Notification/notification_internal.h +++ b/Source/Services/Notification/notification_internal.h @@ -40,7 +40,7 @@ public: PendingUnregistration, Registered, Registering - } m_registrationStatus; + } m_registrationStatus{ RegistrationStatus::Unregistered }; NotificationService( _In_ User&& user, @@ -78,7 +78,7 @@ protected: std::shared_ptr m_contextSettings; String m_endpointId; - bool m_isInitialized; + bool m_isInitialized{ false }; std::recursive_mutex m_mutex; }; @@ -108,7 +108,7 @@ public: GameInviteNotificationEventArgs& operator=(GameInviteNotificationEventArgs other) noexcept = delete; static Result Deserialize( - const JsonValue& json + _In_ const JsonValue& json ) noexcept; private: diff --git a/Source/Services/Notification/notification_service.cpp b/Source/Services/Notification/notification_service.cpp index 60f565e0..e260d1d7 100644 --- a/Source/Services/Notification/notification_service.cpp +++ b/Source/Services/Notification/notification_service.cpp @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "shared_macros.h" -#include "xbox_system_factory.h" -#include "xbox_live_app_config_internal.h" #include "xbox_live_context_internal.h" #include "notification_internal.h" @@ -180,10 +177,11 @@ HRESULT NotificationService::RegisterForNotificationsHelper( payload.AddMember("transportPath", JsonValue(AppConfig::Instance()->APNSEnvironment().c_str(), allocator).Move(), allocator); #elif HC_PLATFORM == HC_PLATFORM_ANDROID payload.AddMember("transport", "FCM", allocator); -#elif HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK +#elif HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK || HC_PLATFORM_IS_EXTERNAL payload.AddMember("transport", "RTA", allocator); #endif - payload.AddMember("locale", JsonValue(utils::get_locales().c_str(), allocator).Move(), allocator); + xsapi_internal_string locale = utils::get_locales(); + payload.AddMember("locale", JsonValue(locale.c_str(), allocator).Move(), allocator); payload.AddMember("titleId", JsonValue(titleId.c_str(), allocator).Move(), allocator); if (!deviceName.empty()) diff --git a/Source/Services/Presence/device_presence_change_subscription.cpp b/Source/Services/Presence/device_presence_change_subscription.cpp index 4c8042f6..0b2fb4cf 100644 --- a/Source/Services/Presence/device_presence_change_subscription.cpp +++ b/Source/Services/Presence/device_presence_change_subscription.cpp @@ -49,7 +49,7 @@ void DevicePresenceChangeSubscription::OnEvent( auto presenceService{ m_presenceService.lock() }; if (presenceService && data.IsString()) { - auto devicePresenceValues = utils::string_split(String{ data.GetString() }, ':'); + auto devicePresenceValues = utils::string_split_internal(String{ data.GetString() }, ':'); if (devicePresenceValues.size() == 2) { presenceService->HandleDevicePresenceChanged( diff --git a/Source/Services/Presence/presence_device_record.cpp b/Source/Services/Presence/presence_device_record.cpp index 6132b5ce..2725a952 100644 --- a/Source/Services/Presence/presence_device_record.cpp +++ b/Source/Services/Presence/presence_device_record.cpp @@ -125,7 +125,7 @@ Result DeviceRecord::DeserializeTitleRecord(_In_ const J } } - if (!errc) + if (SUCCEEDED(errc)) { titleRecord.titleName = Make(titleName); titleRecord.richPresenceString = Make(richPresenceString); @@ -154,7 +154,7 @@ Result DeviceRecord::DeserializeBroadcastRecord(_In_ xsapi_internal_string broadcastId; RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "id", broadcastId)); - if (!errc) + if (SUCCEEDED(errc)) { broadcastRecord.broadcastId = Make(broadcastId); } diff --git a/Source/Services/Presence/presence_internal.h b/Source/Services/Presence/presence_internal.h index d98bfc0c..73ac2389 100644 --- a/Source/Services/Presence/presence_internal.h +++ b/Source/Services/Presence/presence_internal.h @@ -91,7 +91,7 @@ public: protected: void OnSubscribe(const JsonValue& data) noexcept override; - void OnEvent(const JsonValue& event) noexcept override; + void OnEvent(_In_ const JsonValue& event) noexcept override; void OnResync() noexcept override; private: diff --git a/Source/Services/Presence/presence_service.cpp b/Source/Services/Presence/presence_service.cpp index 28db600b..3258f09c 100644 --- a/Source/Services/Presence/presence_service.cpp +++ b/Source/Services/Presence/presence_service.cpp @@ -309,12 +309,6 @@ HRESULT PresenceService::SetPresence( { heartbeatDelayInMins = 5; } - - auto xsapiSingleton = get_xsapi_singleton(); - if (xsapiSingleton && xsapiSingleton->m_onSetPresenceFinish) - { - xsapiSingleton->m_onSetPresenceFinish(heartbeatDelayInMins); - } } async.Complete(hr); } }); diff --git a/Source/Services/Privacy/permission_check_result.cpp b/Source/Services/Privacy/permission_check_result.cpp index 38fb2543..59b31074 100644 --- a/Source/Services/Privacy/permission_check_result.cpp +++ b/Source/Services/Privacy/permission_check_result.cpp @@ -95,7 +95,7 @@ Result PermissionCheckResult::Deserialize( result.reasons = result.m_reasons.data(); result.reasonsCount = result.m_reasons.size(); - if (errc) + if (FAILED(errc)) { return WEB_E_INVALID_JSON_STRING; } diff --git a/Source/Services/Privacy/privacy_api.cpp b/Source/Services/Privacy/privacy_api.cpp index d228697d..c91d4d5e 100644 --- a/Source/Services/Privacy/privacy_api.cpp +++ b/Source/Services/Privacy/privacy_api.cpp @@ -354,7 +354,7 @@ STDAPI XblPrivacyBatchCheckPermissionResult( RETURN_HR_INVALIDARGUMENT_IF(results == nullptr || resultsCount == nullptr); // bufferUsed is needed to calculate resultsCount - auto bufferUsedPtr = std::make_unique(); + auto bufferUsedPtr = MakeUnique(); if (bufferUsed == nullptr) { bufferUsed = bufferUsedPtr.get(); diff --git a/Source/Services/Privacy/privacy_service.cpp b/Source/Services/Privacy/privacy_service.cpp index 424d14c8..30dd76f8 100644 --- a/Source/Services/Privacy/privacy_service.cpp +++ b/Source/Services/Privacy/privacy_service.cpp @@ -122,12 +122,12 @@ HRESULT PrivacyService::CheckPermission( { // users/xuid({xuid})/permission/validate?setting={setting}&target={target}) xbox::services::uri_builder subPathBuilder; - stringstream_t path; - path << _T("/users/xuid(") << m_user.Xuid() << _T(")/permission/validate"); + xsapi_internal_stringstream path; + path << "/users/xuid(" << m_user.Xuid() << ")/permission/validate"; subPathBuilder.append_path(path.str()); - subPathBuilder.append_query(_T("setting"), StringTFromUtf8(XblPermissionName(permission).data())); - subPathBuilder.append_query(_T("target"), StringTFromUtf8(targetQuery.data())); + subPathBuilder.append_query("setting", XblPermissionName(permission).data()); + subPathBuilder.append_query("target", targetQuery); Result userResult = m_user.Copy(); RETURN_HR_IF_FAILED(userResult.Hresult()); @@ -136,7 +136,7 @@ HRESULT PrivacyService::CheckPermission( RETURN_HR_IF_FAILED(httpCall->Init( m_contextSettings, "GET", - XblHttpCall::BuildUrl("privacy", utils::internal_string_from_string_t(subPathBuilder.to_string())), + XblHttpCall::BuildUrl("privacy", subPathBuilder.to_string()), xbox_live_api::check_permission_with_target_user )); @@ -261,7 +261,7 @@ Result> PrivacyService::DeserializeUserList( uint64_t xuid = 0; HRESULT tempErr = JsonUtils::ExtractJsonXuid(json, "xuid", xuid, true); - if (tempErr) + if (FAILED(tempErr)) { errc = tempErr; } @@ -271,7 +271,7 @@ Result> PrivacyService::DeserializeUserList( json, ("users"), xuids, true )); - if (errc) + if (FAILED(errc)) { return WEB_E_INVALID_JSON_STRING; } diff --git a/Source/Services/RealTimeActivityManager/real_time_activity_api.cpp b/Source/Services/RealTimeActivityManager/real_time_activity_api.cpp index f0c27012..4644c1e0 100644 --- a/Source/Services/RealTimeActivityManager/real_time_activity_api.cpp +++ b/Source/Services/RealTimeActivityManager/real_time_activity_api.cpp @@ -72,7 +72,7 @@ STDAPI_(XblFunctionContext) XblRealTimeActivityAddConnectionStateChangeHandler( { try { - handler(context, state); + handler(context, state); } catch (...) { diff --git a/Source/Services/RealTimeActivityManager/real_time_activity_connection.cpp b/Source/Services/RealTimeActivityManager/real_time_activity_connection.cpp index 9574e857..17336397 100644 --- a/Source/Services/RealTimeActivityManager/real_time_activity_connection.cpp +++ b/Source/Services/RealTimeActivityManager/real_time_activity_connection.cpp @@ -116,7 +116,8 @@ Result> Connection::Make( std::move(stateChangedHandler), std::move(resyncHandler) }, - Deleter() + Deleter(), + Allocator() ); auto hr = rtaConnection->InitializeWebsocket(); @@ -171,12 +172,15 @@ void Connection::Cleanup() m_unsubscribeAsyncContexts.clear(); lock.unlock(); - m_queue.Terminate(true); - - for (auto& async : pendingAsyncContexts) - { - async.Complete(E_ABORT); - } + m_queue.Terminate( + false, + [pendingAsyncContexts = std::move(pendingAsyncContexts)]() { + for (auto& async : pendingAsyncContexts) + { + async.Complete(E_ABORT); + } + } + ); } #if HC_PLATFORM == HC_PLATFORM_GDK diff --git a/Source/Services/RealTimeActivityManager/real_time_activity_manager.cpp b/Source/Services/RealTimeActivityManager/real_time_activity_manager.cpp index 8f3ea282..cc79261b 100644 --- a/Source/Services/RealTimeActivityManager/real_time_activity_manager.cpp +++ b/Source/Services/RealTimeActivityManager/real_time_activity_manager.cpp @@ -81,6 +81,7 @@ HRESULT RealTimeActivityManager::RemoveSubscription( if (iter != sharedThis->m_rtaConnections.end() && iter->second->SubscriptionCount() == 0 && sharedThis->m_legacyActivations[xuid] == 0) { LOGS_DEBUG << __FUNCTION__ << ": No remaining activations or subscriptions, tearing down connection"; + iter->second->Cleanup(); sharedThis->m_rtaConnections.erase(iter); // Maintain legacy behavior and raise Disconnected event even on intentional shutdown @@ -147,7 +148,7 @@ void RealTimeActivityManager::Activate( if (titleActivation) { m_titleActivated = true; - GetConnection(user); + (void)GetConnection(user); } } @@ -173,7 +174,8 @@ void RealTimeActivityManager::Deactivate( if (m_titleActivated || connectionIter->second->SubscriptionCount() == 0) { LOGS_DEBUG << __FUNCTION__ << ": No remaining activations tearing down connection"; - m_rtaConnections.erase(user.Xuid()); + connectionIter->second->Cleanup(); + m_rtaConnections.erase(connectionIter); // Maintain legacy behavior and raise Disconnected event even on intentional shutdown auto handlers{ m_stateChangedHandlers[user.Xuid()] }; diff --git a/Source/Services/RealTimeActivityManager/real_time_activity_manager.h b/Source/Services/RealTimeActivityManager/real_time_activity_manager.h index a2b608a7..b1cf0fe7 100644 --- a/Source/Services/RealTimeActivityManager/real_time_activity_manager.h +++ b/Source/Services/RealTimeActivityManager/real_time_activity_manager.h @@ -77,7 +77,7 @@ private: // Legacy API support Map m_legacyActivations; - bool m_titleActivated; + bool m_titleActivated{ false }; mutable std::recursive_mutex m_lock; }; diff --git a/Source/Services/Social/Manager/social_graph.cpp b/Source/Services/Social/Manager/social_graph.cpp index 6024ca51..b95fadf7 100644 --- a/Source/Services/Social/Manager/social_graph.cpp +++ b/Source/Services/Social/Manager/social_graph.cpp @@ -48,7 +48,7 @@ struct ServiceCallManager : public std::enable_shared_from_this lock) noexcept; @@ -145,7 +145,11 @@ Result> SocialGraph::Make( return userResult.Hresult(); } - auto graph = std::shared_ptr(new (Alloc(sizeof(SocialGraph))) SocialGraph{ userResult.ExtractPayload(), queue, rtaManager }); + auto graph = std::shared_ptr( + new (Alloc(sizeof(SocialGraph))) SocialGraph{ userResult.ExtractPayload(), queue, rtaManager }, + Deleter(), + Allocator() + ); auto hr = graph->Initialize(); if (FAILED(hr)) { @@ -188,7 +192,7 @@ Result> SocialGraph::Make( { if (auto graph{ weakGraph.lock() }) { - graph->m_serviceCallManager->PeopleHubGetFollwedUsers([weakGraph](Vector&& profiles) + graph->m_serviceCallManager->PeopleHubGetFollowedUsers([weakGraph](Vector&& profiles) { if (auto graph{ weakGraph.lock() }) { @@ -299,8 +303,8 @@ std::shared_ptr SocialGraph::LocalUser() const noexcept } void SocialGraph::DoWork( - _Out_ Vector& events, - _Out_ Vector>& affectedUsers + _Inout_ Vector& events, + _Inout_ Vector>& affectedUsers ) noexcept { PERF_START(); @@ -621,8 +625,8 @@ void SocialGraph::AddOrUpdateEvent( } void SocialGraph::ApplyGraphUpdates( - _Out_ Vector& events, - _Out_ Vector>& affectedUsers + _Inout_ Vector& events, + _Inout_ Vector>& affectedUsers ) noexcept { PERF_START(); @@ -828,7 +832,7 @@ HRESULT ServiceCallManager::PollPeopleHub(const Vector& xuids) noexcep return S_OK; } -HRESULT ServiceCallManager::PeopleHubGetFollwedUsers(PeopleHubResultHandler handler) const noexcept +HRESULT ServiceCallManager::PeopleHubGetFollowedUsers(PeopleHubResultHandler handler) const noexcept { return m_peoplehubService->GetSocialGraph(m_localUserXuid, m_peoplehubDetailLevel, { m_queue, [ @@ -844,7 +848,7 @@ HRESULT ServiceCallManager::PeopleHubGetFollwedUsers(PeopleHubResultHandler hand { if (auto sharedThis{ weakThis.lock() }) { - PeopleHubGetFollwedUsers(handler); + PeopleHubGetFollowedUsers(handler); } }, c_failureRetryIntervalMs); } diff --git a/Source/Services/Social/Manager/social_graph.h b/Source/Services/Social/Manager/social_graph.h index f50f38a1..1e0ad9c5 100644 --- a/Source/Services/Social/Manager/social_graph.h +++ b/Source/Services/Social/Manager/social_graph.h @@ -65,8 +65,8 @@ public: // Appends XblSocialManagerEvents describing the updates to 'events' list. Appends all affected users to the list of affected users. // This is used to maintain their lifetime since the events reference them. void DoWork( - _Out_ Vector& events, - _Out_ Vector>& affectedUsers + _Inout_ Vector& events, + _Inout_ Vector>& affectedUsers ) noexcept; // Registers/Unregisters an XblSocialManagerUserGroup backed by this graph. Registered groups @@ -126,8 +126,8 @@ private: // Applies all pending updates to local graph. Updates events and affected users void ApplyGraphUpdates( - _Out_ Vector& events, - _Out_ Vector>& affectedUsers + _Inout_ Vector& events, + _Inout_ Vector>& affectedUsers ) noexcept; static ProfileChanges CompareProfiles( diff --git a/Source/Services/Social/Manager/social_manager_api.cpp b/Source/Services/Social/Manager/social_manager_api.cpp index 6105c956..b5e8a5f8 100644 --- a/Source/Services/Social/Manager/social_manager_api.cpp +++ b/Source/Services/Social/Manager/social_manager_api.cpp @@ -131,19 +131,19 @@ CATCH_RETURN() STDAPI XblSocialManagerUserGroupGetUsers( _In_ XblSocialManagerUserGroupHandle groupHandle, - _Outptr_ XblSocialManagerUserPtrArray* users, + _Outptr_result_maybenull_ XblSocialManagerUserPtrArray* users, _Out_ size_t* usersCount ) XBL_NOEXCEPT try { + RETURN_HR_INVALIDARGUMENT_IF(groupHandle == nullptr || users == nullptr || usersCount == nullptr); + *users = nullptr; + return ApiImpl([&](SocialManager& socialManager) { - RETURN_HR_INVALIDARGUMENT_IF(groupHandle == nullptr || users == nullptr || usersCount == nullptr); - auto group{ socialManager.GetUserGroup(groupHandle) }; if (!group) { - *users = nullptr; *usersCount = 0; return E_UNEXPECTED; } @@ -157,19 +157,19 @@ CATCH_RETURN() STDAPI XblSocialManagerUserGroupGetUsersTrackedByGroup( _In_ XblSocialManagerUserGroupHandle groupHandle, - _Outptr_ const uint64_t** trackedUsers, + _Outptr_result_maybenull_ const uint64_t** trackedUsers, _Out_ size_t* trackedUsersCount ) XBL_NOEXCEPT try { + RETURN_HR_INVALIDARGUMENT_IF(groupHandle == nullptr || trackedUsers == nullptr || trackedUsersCount == nullptr); + *trackedUsers = nullptr; + return ApiImpl([&](SocialManager& socialManager) { - RETURN_HR_INVALIDARGUMENT_IF(groupHandle == nullptr || trackedUsers == nullptr || trackedUsersCount == nullptr); - auto group{ socialManager.GetUserGroup(groupHandle) }; if (!group) { - *trackedUsers = nullptr; *trackedUsersCount = 0; return E_UNEXPECTED; } diff --git a/Source/Services/Social/Manager/social_manager_user_group.cpp b/Source/Services/Social/Manager/social_manager_user_group.cpp index 9fe4dcf8..5b7673df 100644 --- a/Source/Services/Social/Manager/social_manager_user_group.cpp +++ b/Source/Services/Social/Manager/social_manager_user_group.cpp @@ -50,8 +50,11 @@ std::shared_ptr XblSocialManagerUserGroup::Make( XblRelationshipFilter relationshipFilter ) noexcept { - auto buffer = Alloc(sizeof(XblSocialManagerUserGroup)); - auto group = std::shared_ptr(new (buffer) XblSocialManagerUserGroup{ socialGraph, presenceFilter, relationshipFilter }); + auto group = std::shared_ptr( + new (Alloc(sizeof(XblSocialManagerUserGroup))) XblSocialManagerUserGroup{ socialGraph, presenceFilter, relationshipFilter }, + Deleter(), + Allocator() + ); socialGraph->RegisterGroup(group); return group; } @@ -61,8 +64,11 @@ std::shared_ptr XblSocialManagerUserGroup::Make( Vector&& trackedUsers ) noexcept { - auto buffer = Alloc(sizeof(XblSocialManagerUserGroup)); - auto group = std::shared_ptr(new (buffer) XblSocialManagerUserGroup{ socialGraph, std::move(trackedUsers) }); + auto group = std::shared_ptr( + new (Alloc(sizeof(XblSocialManagerUserGroup))) XblSocialManagerUserGroup{ socialGraph, std::move(trackedUsers) }, + Deleter(), + Allocator() + ); socialGraph->RegisterGroup(group); return group; } diff --git a/Source/Services/Social/social_internal.h b/Source/Services/Social/social_internal.h index 7025c979..4f1993aa 100644 --- a/Source/Services/Social/social_internal.h +++ b/Source/Services/Social/social_internal.h @@ -42,12 +42,12 @@ namespace legacy /// /// Returns Favorites constant string /// - static const string_t favorite() { return _T("Favorites"); } + static const char* favorite() { return "Favorites"; } /// /// Returns People constant string /// - static const string_t people() { return _T("People"); } + static const char* people() { return "People"; } }; } diff --git a/Source/Services/Social/social_relationship_result.cpp b/Source/Services/Social/social_relationship_result.cpp index 4f4a3bd3..35cf2851 100644 --- a/Source/Services/Social/social_relationship_result.cpp +++ b/Source/Services/Social/social_relationship_result.cpp @@ -41,8 +41,8 @@ Result> XblSocialRelationshipResult RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(person, "isFavorite", relationship.isFavorite)); RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(person, "isFollowingCaller", relationship.isFollowingCaller)); - xsapi_internal_vector socialNetworksInternalVector; - JsonUtils::ExtractJsonVector(JsonUtils::JsonStringTExtractor, person, "socialNetworks", socialNetworksInternalVector, false); + xsapi_internal_vector socialNetworksInternalVector; + JsonUtils::ExtractJsonVector(JsonUtils::JsonStringExtractor, person, "socialNetworks", socialNetworksInternalVector, false); UTF8StringArray socialNetworks(socialNetworksInternalVector); relationship.socialNetworks = socialNetworks.Data(); relationship.socialNetworksCount = socialNetworks.Size(); diff --git a/Source/Services/Stats/title_managed_statistics_internal.h b/Source/Services/Stats/title_managed_statistics_internal.h index 81bd369f..762af095 100644 --- a/Source/Services/Stats/title_managed_statistics_internal.h +++ b/Source/Services/Stats/title_managed_statistics_internal.h @@ -33,7 +33,7 @@ struct TitleManagedStatistic String = static_cast(XblTitleManagedStatType::String), Null } type; - double numberValue; + double numberValue{ 0.0 }; String stringValue; }; diff --git a/Source/Services/Stats/title_managed_statistics_service.cpp b/Source/Services/Stats/title_managed_statistics_service.cpp index 3c98e2d0..0b201d7f 100644 --- a/Source/Services/Stats/title_managed_statistics_service.cpp +++ b/Source/Services/Stats/title_managed_statistics_service.cpp @@ -28,7 +28,7 @@ HRESULT TitleManagedStatisticsService::WriteTitleManagedStatisticsAsync( request.AddMember("$schema", "http://stats.xboxlive.com/2017-1/schema#", allocator); request.AddMember("previousRevision", 0, allocator); request.AddMember("revision", GetRevisionFromClock(), allocator); - request.AddMember("timestamp", JsonValue(utils::internal_string_from_string_t(xbox::services::datetime::utc_now().to_string(xbox::services::datetime::date_format::ISO_8601)).c_str(), allocator).Move(), allocator); + request.AddMember("timestamp", JsonValue(xbox::services::datetime::utc_now().to_string(xbox::services::datetime::date_format::ISO_8601).c_str(), allocator).Move(), allocator); Result userResult = m_user.Copy(); RETURN_HR_IF_FAILED(userResult.Hresult()); diff --git a/Source/Services/Stats/user_statistics_internal.h b/Source/Services/Stats/user_statistics_internal.h index 98077207..ff5f0e2c 100644 --- a/Source/Services/Stats/user_statistics_internal.h +++ b/Source/Services/Stats/user_statistics_internal.h @@ -147,8 +147,8 @@ public: ) noexcept; protected: - void OnSubscribe(const JsonValue& data) noexcept override; - void OnEvent(const JsonValue& data) noexcept override; + void OnSubscribe(_In_ const JsonValue& data) noexcept override; + void OnEvent(_In_ const JsonValue& data) noexcept override; void OnResync() noexcept override; private: diff --git a/Source/Services/Stats/user_statistics_service.cpp b/Source/Services/Stats/user_statistics_service.cpp index 9e6d001f..8f16d929 100644 --- a/Source/Services/Stats/user_statistics_service.cpp +++ b/Source/Services/Stats/user_statistics_service.cpp @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "xbox_system_factory.h" -#include "xsapi_utils.h" #include "user_statistics_internal.h" #include "xbox_live_context_internal.h" #include "real_time_activity_manager.h" diff --git a/Source/Services/StringVerify/string_service.cpp b/Source/Services/StringVerify/string_service.cpp index d26a48dc..1517d41f 100644 --- a/Source/Services/StringVerify/string_service.cpp +++ b/Source/Services/StringVerify/string_service.cpp @@ -2,10 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" -#include "shared_macros.h" -#include "xbox_system_factory.h" #include "string_service_internal.h" -#include "xbox_live_app_config_internal.h" #include "xbox_live_context_internal.h" using namespace xbox::services; diff --git a/Source/Services/TCUI/Android/title_callable_ui_android.cpp b/Source/Services/TCUI/Android/title_callable_ui_android.cpp index e6095c95..9e41283d 100644 --- a/Source/Services/TCUI/Android/title_callable_ui_android.cpp +++ b/Source/Services/TCUI/Android/title_callable_ui_android.cpp @@ -12,7 +12,7 @@ #include "a/java_interop.h" #include "a/jni_utils.h" #include "TCUI/Android/title_callable_ui_jni.h" -#include "xbox_system_factory.h" + using namespace pplx; NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN @@ -80,8 +80,7 @@ title_callable_ui::show_profile_card_ui( .then([](int32_t errorCode) { title_callable_ui_internal::s_isTcuiRunning = false; - auto user = get_xsapi_singleton()->m_lastSignedInUser.exchange(nullptr); - XalUserCloseHandle(user); + (void) java_interop::get_java_interop_singleton()->ExtractStoredUser(); return xbox_live_result(xbox_live_result()); }); @@ -96,11 +95,10 @@ title_callable_ui::show_profile_card_ui( JNI_ATTACH_THREAD(jvm, jniEnv); jmethodID showProfileCardUIMethodId = jniEnv->GetStaticMethodID(interopTcuiClass, "ShowProfileCardUI", "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - if (showProfileCardUIMethodId != NULL && user != nullptr) + auto wrapUserResult = User::WrapHandle(user); + if (showProfileCardUIMethodId != NULL && Succeeded(wrapUserResult)) { - xbox_live_user_t userCopy = nullptr; - XalUserDuplicateHandle(user, &userCopy); - get_xsapi_singleton()->m_lastSignedInUser.store(userCopy); + java_interop::get_java_interop_singleton()->StoreUser(wrapUserResult.ExtractPayload()); title_callable_ui_internal::s_isTcuiRunning = true; uint64_t xuid; @@ -122,7 +120,6 @@ title_callable_ui::show_profile_card_ui( privilegesSS << " " << XalPrivilege::XalPrivilege_AddFriends; } - xbox_system_factory::set_http_call_user(user); auto currentUserIdString = jniEnv->NewStringUTF(xuidSS.str().data()); auto targetUserIdString = jniEnv->NewStringUTF(targetXboxUserId.c_str()); auto currentUserPrivileges = jniEnv->NewStringUTF(privilegesSS.str().data()); diff --git a/Source/Services/TCUI/UWP/title_callable_ui_uwp.cpp b/Source/Services/TCUI/UWP/title_callable_ui_uwp.cpp index 7df2d521..9cd5895e 100644 --- a/Source/Services/TCUI/UWP/title_callable_ui_uwp.cpp +++ b/Source/Services/TCUI/UWP/title_callable_ui_uwp.cpp @@ -16,9 +16,8 @@ #include #include -#include "auth_config.h" -#include "xbox_system_factory.h" #include "xsapi-cpp/title_callable_ui.h" +#include "local_config.h" #define XBOX_APP_PFN _T("Microsoft.XboxApp_8wekyb3d8bbwe") #define XBOX_DEEPLINK_FRIEND_FINDER _T("xbox-friendfinder:facebook") @@ -126,7 +125,7 @@ pplx::task > create_exception_free_task( catch (Platform::Exception^ e) { xbox_live_error_code errc = static_cast(e->HResult); - return xbox_live_result(errc, xbox::services::convert::to_utf8string(e->Message->Data())); + return xbox_live_result(errc, xbox::services::convert::utf16_to_utf8(e->Message->Data())); } #endif }); @@ -599,17 +598,19 @@ void title_callable_ui::_Get_gaming_privilege_scope_policy( ) { auto localConfig{ AppConfig::Instance()->LocalConfig() }; - auth_config authConfig( - localConfig->sandbox(), - localConfig->environment_prefix(), - localConfig->environment(), - localConfig->use_first_party_token(), - localConfig->is_creators_title(), - localConfig->scope() - ); - scope = PLATFORM_STRING_FROM_INTERNAL_STRING(authConfig.rps_ticket_service()); - policy = PLATFORM_STRING_FROM_INTERNAL_STRING(authConfig.rps_ticket_policy()); + String rpsTicketService{ localConfig->scope() }; + if (!localConfig->is_creators_title() && localConfig->use_first_party_token()) + { + Stringstream ss; + ss << "open-user.auth" << localConfig->environment() << ".xboxlive.com"; + rpsTicketService = ss.str(); + } + + String rpsTicketPolicy{ localConfig->use_first_party_token() ? "MBI_SSL" : "DELEGATION" }; + + scope = PLATFORM_STRING_FROM_INTERNAL_STRING(rpsTicketService); + policy = PLATFORM_STRING_FROM_INTERNAL_STRING(rpsTicketPolicy); } xbox::services::xbox_live_result title_callable_ui::check_gaming_privilege_silently( diff --git a/Source/Services/TitleStorage/title_storage_service.cpp b/Source/Services/TitleStorage/title_storage_service.cpp index 1832aa0a..c9a3bddb 100644 --- a/Source/Services/TitleStorage/title_storage_service.cpp +++ b/Source/Services/TitleStorage/title_storage_service.cpp @@ -3,8 +3,6 @@ #include "pch.h" #include "title_storage_internal.h" -#include "xbox_system_factory.h" -#include "xsapi_utils.h" NAMESPACE_MICROSOFT_XBOX_SERVICES_TITLE_STORAGE_CPP_BEGIN @@ -101,7 +99,7 @@ TitleStorageService::DeserializeTitleStorageQuota( } } - if (errc) + if (FAILED(errc)) { return E_FAIL; } @@ -662,7 +660,7 @@ TitleStorageService::TitleStorageBlobMetadataSubpath( continuationToken ); - xsapi_internal_string paramPath = utils::internal_string_from_string_t(params.query()); + xsapi_internal_string paramPath = params.query(); if (paramPath.size() > 1) { path << "?" << paramPath; diff --git a/Source/Shared/HookedUri/asyncrt_utils.h b/Source/Shared/HookedUri/asyncrt_utils.h new file mode 100644 index 00000000..a3089318 --- /dev/null +++ b/Source/Shared/HookedUri/asyncrt_utils.h @@ -0,0 +1,607 @@ +/*** +* Copyright (C) Microsoft. All rights reserved. +* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +* +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Various common utilities. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "HookedUri/details/basic_types.h" + +#if !defined(_WIN32) || (_MSC_VER >= 1700) +#include +#endif + +#ifndef _WIN32 +#include +#endif + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 26444 ) // ignore various unnamed objects +#endif + +namespace xbox { namespace services { namespace cppresturi { + +/// Various utilities for string conversions and date and time manipulation. +namespace utility +{ + +// Left over from VS2010 support, remains to avoid breaking. +typedef std::chrono::seconds seconds; + +/// Functions for converting to/from std::chrono::seconds to xml string. +namespace timespan +{ + /// + /// Converts a timespan/interval in seconds to xml duration string as specified by + /// http://www.w3.org/TR/xmlschema-2/#duration + /// + utility::string_t seconds_to_xml_duration(utility::seconds numSecs); + + /// + /// Converts an xml duration to timespan/interval in seconds + /// http://www.w3.org/TR/xmlschema-2/#duration + /// + utility::seconds xml_duration_to_seconds(const utility::string_t ×panString); +} + +/// Functions for Unicode string conversions. +namespace conversions +{ + /// + /// Converts a UTF-16 string to a UTF-8 string. + /// + /// A two byte character UTF-16 string. + /// A single byte character UTF-8 string. + xsapi_internal_string utf16_to_utf8_internal(const xsapi_internal_wstring &w); + std::string utf16_to_utf8(const utf16string&w); + + /// + /// Converts a UTF-8 string to a UTF-16 + /// + /// A single byte character UTF-8 string. + /// A two byte character UTF-16 string. + utf16string utf8_to_utf16(const std::string &s); + + /// + /// Converts a ASCII (us-ascii) string to a UTF-16 string. + /// + /// A single byte character us-ascii string. + /// A two byte character UTF-16 string. + utf16string usascii_to_utf16(const std::string &s); + + /// + /// Converts a Latin1 (iso-8859-1) string to a UTF-8 string. + /// + /// A single byte character UTF-8 string. + /// A single byte character UTF-8 string. + utf8string latin1_to_utf8(const std::string &s); + + /// + /// Converts to a platform dependent Unicode string type. + /// + /// A single byte character UTF-8 string. + /// A platform dependent string type. + utility::string_t to_string_t(std::string &&s); + + /// + /// Converts to a platform dependent Unicode string type. + /// + /// A two byte character UTF-16 string. + /// A platform dependent string type. + utility::string_t to_string_t(utf16string &&s); + + /// + /// Converts to a platform dependent Unicode string type. + /// + /// A single byte character UTF-8 string. + /// A platform dependent string type. + utility::string_t to_string_t(const std::string &s); + + /// + /// Converts to a platform dependent Unicode string type. + /// + /// A two byte character UTF-16 string. + /// A platform dependent string type. + utility::string_t to_string_t(const utf16string &s); + + /// + /// Converts to a UTF-16 from string. + /// + /// A single byte character UTF-8 string. + /// A two byte character UTF-16 string. + utf16string to_utf16string(const std::string &value); + + /// + /// Converts to a UTF-16 from string. + /// + /// A two byte character UTF-16 string. + /// A two byte character UTF-16 string. + utf16string to_utf16string(utf16string value); + + /// + /// Converts to a UTF-8 string. + /// + /// A single byte character UTF-8 string. + /// A single byte character UTF-8 string. + xsapi_internal_string to_utf8string_internal(xsapi_internal_string value); + + /// + /// Converts to a UTF-8 string. + /// + /// A two byte character UTF-16 string. + /// A single byte character UTF-8 string. + xsapi_internal_string to_utf8string_internal(const xsapi_internal_wstring &value); + + xsapi_internal_string latin1_to_utf8_internal(const xsapi_internal_string &s); + xsapi_internal_wstring latin1_to_utf16_internal(const xsapi_internal_string &s); + + /// + /// Encode the given byte array into a base64 string + /// + utility::string_t to_base64(const unsigned char* data, size_t dataSize); + + /// + /// Encode the given byte array into a base64 string + /// + utility::string_t to_base64(const std::vector& data); + + /// + /// Encode the given 8-byte integer into a base64 string + /// + utility::string_t to_base64(uint64_t data); + + /// + /// Decode the given base64 string to a byte array + /// + std::vector from_base64(const utility::string_t& str); + + template + utility::string_t print_string(const Source &val, const std::locale &loc) + { + utility::ostringstream_t oss; + oss.imbue(loc); + oss << val; + if (oss.bad()) + { + throw std::bad_cast(); + } + return oss.str(); + } + + template + utility::string_t print_string(const Source &val) + { + return print_string(val, std::locale()); + } + + inline utility::string_t print_string(const utility::string_t &val) + { + return val; + } + + template + Target scan_string(const utility::string_t &str, const std::locale &loc) + { + Target t; + utility::istringstream_t iss(str); + iss.imbue(loc); + iss >> t; + if (iss.bad()) + { + throw std::bad_cast(); + } + return t; + } + + template + Target scan_string(const utility::string_t &str) + { + return scan_string(str, std::locale()); + } + + inline utility::string_t scan_string(const utility::string_t &str) + { + return str; + } +} + +namespace details +{ + /// + /// Cross platform RAII container for setting thread local locale. + /// + class scoped_c_thread_locale + { + public: + _ASYNCRTIMP scoped_c_thread_locale(); + _ASYNCRTIMP ~scoped_c_thread_locale(); + +#if !defined(ANDROID) && !defined(__ANDROID__) // CodePlex 269 +#ifdef _WIN32 + typedef _locale_t xplat_locale; +#else + typedef locale_t xplat_locale; +#endif + + static _ASYNCRTIMP xplat_locale c_locale(); +#endif + private: +#ifdef _WIN32 + std::string m_prevLocale; + int m_prevThreadSetting; +#elif !(defined(ANDROID) || defined(__ANDROID__)) + locale_t m_prevLocale; +#endif + scoped_c_thread_locale(const scoped_c_thread_locale &); + scoped_c_thread_locale & operator=(const scoped_c_thread_locale &); + }; + + /// + /// Our own implementation of alpha numeric instead of std::isalnum to avoid + /// taking global lock for performance reasons. + /// + inline bool __cdecl is_alnum(char ch) + { + return (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z') + || (ch >= 'a' && ch <= 'z'); + } + + /// + /// Simplistic implementation of make_unique. A better implementation would be based on variadic templates + /// and therefore not be compatible with Dev10. + /// + template + std::unique_ptr<_Type> make_unique() { + return std::unique_ptr<_Type>(new _Type()); + } + + template + std::unique_ptr<_Type> make_unique(_Arg1&& arg1) { + return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1))); + } + + template + std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2) { + return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2))); + } + + template + std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3) { + return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3))); + } + + template + std::unique_ptr<_Type> make_unique(_Arg1&& arg1, _Arg2&& arg2, _Arg3&& arg3, _Arg4&& arg4) { + return std::unique_ptr<_Type>(new _Type(std::forward<_Arg1>(arg1), std::forward<_Arg2>(arg2), std::forward<_Arg3>(arg3), std::forward<_Arg4>(arg4))); + } + + /// + /// Cross platform utility function for performing case insensitive string comparision. + /// + /// First string to compare. + /// Second strong to compare. + /// true if the strings are equivalent, false otherwise + inline bool str_icmp(const utility::string_t &left, const utility::string_t &right) + { +#ifdef _WIN32 + return _wcsicmp(left.c_str(), right.c_str()) == 0; +#else + return strcasecmp(left.c_str(), right.c_str()); +#endif + } + +#ifdef _WIN32 + +/// +/// Category error type for Windows OS errors. +/// +class windows_category_impl : public std::error_category +{ +public: + virtual const char *name() const CPPREST_NOEXCEPT { return "windows"; } + + _ASYNCRTIMP virtual std::string message(int errorCode) const CPPREST_NOEXCEPT; + + _ASYNCRTIMP virtual std::error_condition default_error_condition(int errorCode) const CPPREST_NOEXCEPT; +}; + +/// +/// Gets the one global instance of the windows error category. +/// +/// An error category instance. +_ASYNCRTIMP const std::error_category & __cdecl windows_category(); + +#else + +/// +/// Gets the one global instance of the linux error category. +/// +/// An error category instance. +_ASYNCRTIMP const std::error_category & __cdecl linux_category(); + +#endif + +/// +/// Gets the one global instance of the current platform's error category. +/// +_ASYNCRTIMP const std::error_category & __cdecl platform_category(); + +/// +/// Creates an instance of std::system_error from a OS error code. +/// +inline std::system_error __cdecl create_system_error(unsigned long errorCode) +{ + std::error_code code((int)errorCode, platform_category()); + return std::system_error(code, code.message()); +} + +/// +/// Creates a std::error_code from a OS error code. +/// +inline std::error_code __cdecl create_error_code(unsigned long errorCode) +{ + return std::error_code((int)errorCode, platform_category()); +} + +/// +/// Creates the corresponding error message from a OS error code. +/// +inline utility::string_t __cdecl create_error_message(unsigned long errorCode) +{ + return utility::conversions::to_string_t(create_error_code(errorCode).message()); +} + +} + +class datetime +{ +public: + typedef uint64_t interval_type; + + /// + /// Defines the supported date and time string formats. + /// + enum date_format { RFC_1123, ISO_8601 }; + + /// + /// Returns the current UTC time. + /// + static _ASYNCRTIMP datetime __cdecl utc_now(); + + /// + /// An invalid UTC timestamp value. + /// + enum:interval_type { utc_timestamp_invalid = static_cast(-1) }; + + /// + /// Returns seconds since Unix/POSIX time epoch at 01-01-1970 00:00:00. + /// If time is before epoch, utc_timestamp_invalid is returned. + /// + static interval_type utc_timestamp() + { + const auto seconds = utc_now().to_interval() / _secondTicks; + if (seconds >= 11644473600LL) + { + return seconds - 11644473600LL; + } + else + { + return utc_timestamp_invalid; + } + } + + datetime() : m_interval(0) + { + } + + /// + /// Creates datetime from a string representing time in UTC in RFC 1123 format. + /// + /// Returns a datetime of zero if not successful. + static _ASYNCRTIMP datetime __cdecl from_string(const utility::string_t& timestring, date_format format = RFC_1123); + + /// + /// Returns a string representation of the datetime. + /// + _ASYNCRTIMP xsapi_internal_string to_string_internal(date_format format = RFC_1123) const; + + /// + /// Returns the integral time value. + /// + interval_type to_interval() const + { + return m_interval; + } + + datetime operator- (interval_type value) const + { + return datetime(m_interval - value); + } + + datetime operator+ (interval_type value) const + { + return datetime(m_interval + value); + } + + bool operator== (datetime dt) const + { + return m_interval == dt.m_interval; + } + + bool operator!= (const datetime& dt) const + { + return !(*this == dt); + } + + static interval_type from_milliseconds(unsigned int milliseconds) + { + return milliseconds*_msTicks; + } + + static interval_type from_seconds(unsigned int seconds) + { + return seconds*_secondTicks; + } + + static interval_type from_minutes(unsigned int minutes) + { + return minutes*_minuteTicks; + } + + static interval_type from_hours(unsigned int hours) + { + return hours*_hourTicks; + } + + static interval_type from_days(unsigned int days) + { + return days*_dayTicks; + } + + bool is_initialized() const + { + return m_interval != 0; + } + +private: + + friend int operator- (datetime t1, datetime t2); + + static const interval_type _msTicks = static_cast(10000); + static const interval_type _secondTicks = 1000*_msTicks; + static const interval_type _minuteTicks = 60*_secondTicks; + static const interval_type _hourTicks = 60*60*_secondTicks; + static const interval_type _dayTicks = 24*60*60*_secondTicks; + + +#ifdef _WIN32 + // void* to avoid pulling in windows.h + static _ASYNCRTIMP bool __cdecl system_type_to_datetime(/*SYSTEMTIME*/ void* psysTime, uint64_t seconds, datetime * pdt); +#else + static datetime timeval_to_datetime(const timeval &time); +#endif + + // Private constructor. Use static methods to create an instance. + datetime(interval_type interval) : m_interval(interval) + { + } + + // Storing as hundreds of nanoseconds 10e-7, i.e. 1 here equals 100ns. + interval_type m_interval; +}; + +#ifndef _WIN32 + +// temporary workaround for the fact that +// utf16char is not fully supported in GCC +class cmp +{ +public: + + static int icmp(std::string left, std::string right) + { + size_t i; + for (i = 0; i < left.size(); ++i) + { + if (i == right.size()) return 1; + + auto l = cmp::tolower(left[i]); + auto r = cmp::tolower(right[i]); + if (l > r) return 1; + if (l < r) return -1; + } + if (i < right.size()) return -1; + return 0; + } + +private: + static char tolower(char c) + { + if (c >= 'A' && c <= 'Z') + return static_cast(c - 'A' + 'a'); + return c; + } +}; + +#endif + +inline int operator- (datetime t1, datetime t2) +{ + auto diff = (t1.m_interval - t2.m_interval); + + // Round it down to seconds + diff /= 10 * 1000 * 1000; + + return static_cast(diff); +} + +/// +/// Nonce string generator class. +/// +class nonce_generator +{ +public: + + /// + /// Define default nonce length. + /// + enum { default_length = 32 }; + + /// + /// Nonce generator constructor. + /// + /// Length of the generated nonce string. + nonce_generator(int length=default_length) : + m_random(static_cast(utility::datetime::utc_timestamp())), + m_length(length) + {} + + /// + /// Generate a nonce string containing random alphanumeric characters (A-Za-z0-9). + /// Length of the generated string is set by length(). + /// + /// The generated nonce string. + _ASYNCRTIMP utility::string_t generate(); + + /// + /// Get length of generated nonce string. + /// + /// Nonce string length. + int length() const { return m_length; } + + /// + /// Set length of the generated nonce string. + /// + /// Lenght of nonce string. + void set_length(int length) { m_length = length; } + +private: + static const utility::string_t c_allowed_chars; + std::mt19937 m_random; + int m_length; +}; + +} // namespace utility; + +} } } + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif diff --git a/Source/Shared/HookedUri/base_uri.h b/Source/Shared/HookedUri/base_uri.h new file mode 100644 index 00000000..4f8d2f7d --- /dev/null +++ b/Source/Shared/HookedUri/base_uri.h @@ -0,0 +1,460 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Protocol independent support for URIs. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include +#include +#include +#include +#include + +#include "HookedUri/asyncrt_utils.h" +#include "HookedUri/details/basic_types.h" + +namespace xbox { namespace services { namespace cppresturi { + +namespace web { + + namespace details + { + struct uri_components + { + uri_components() : m_path("/"), m_port(-1) + {} + + uri_components(const uri_components &other) : + m_scheme(other.m_scheme), + m_host(other.m_host), + m_user_info(other.m_user_info), + m_path(other.m_path), + m_query(other.m_query), + m_fragment(other.m_fragment), + m_port(other.m_port) + {} + + uri_components & operator=(const uri_components &other) + { + if (this != &other) + { + m_scheme = other.m_scheme; + m_host = other.m_host; + m_user_info = other.m_user_info; + m_path = other.m_path; + m_query = other.m_query; + m_fragment = other.m_fragment; + m_port = other.m_port; + } + return *this; + } + + uri_components(uri_components &&other) CPPREST_NOEXCEPT : + m_scheme(std::move(other.m_scheme)), + m_host(std::move(other.m_host)), + m_user_info(std::move(other.m_user_info)), + m_path(std::move(other.m_path)), + m_query(std::move(other.m_query)), + m_fragment(std::move(other.m_fragment)), + m_port(other.m_port) + {} + + uri_components & operator=(uri_components &&other) CPPREST_NOEXCEPT + { + if (this != &other) + { + m_scheme = std::move(other.m_scheme); + m_host = std::move(other.m_host); + m_user_info = std::move(other.m_user_info); + m_path = std::move(other.m_path); + m_query = std::move(other.m_query); + m_fragment = std::move(other.m_fragment); + m_port = other.m_port; + } + return *this; + } + + xsapi_internal_string join(); + + xsapi_internal_string m_scheme; + xsapi_internal_string m_host; + xsapi_internal_string m_user_info; + xsapi_internal_string m_path; + xsapi_internal_string m_query; + xsapi_internal_string m_fragment; + int m_port; + }; + } + + /// + /// A single exception type to represent errors in parsing, encoding, and decoding URIs. + /// + class uri_exception : public std::exception + { + public: + + uri_exception(std::string msg) : m_msg(std::move(msg)) {} + + ~uri_exception() CPPREST_NOEXCEPT {} + + const char* what() const CPPREST_NOEXCEPT + { + return m_msg.c_str(); + } + + private: + std::string m_msg; + }; + + /// + /// A flexible, protocol independent URI implementation. + /// + /// URI instances are immutable. Querying the various fields on an emtpy URI will return empty strings. Querying + /// various diagnostic members on an empty URI will return false. + /// + /// + /// This implementation accepts both URIs ('http://msn.com/path') and URI relative-references + /// ('/path?query#frag'). + /// + /// This implementation does not provide any scheme-specific handling -- an example of this + /// would be the following: 'http://path1/path'. This is a valid URI, but it's not a valid + /// http-uri -- that is, it's syntactically correct but does not conform to the requirements + /// of the http scheme (http requires a host). + /// We could provide this by allowing a pluggable 'scheme' policy-class, which would provide + /// extra capability for validating and canonicalizing a URI according to scheme, and would + /// introduce a layer of type-safety for URIs of differing schemes, and thus differing semantics. + /// + /// One issue with implementing a scheme-independent URI facility is that of comparing for equality. + /// For instance, these URIs are considered equal 'http://msn.com', 'http://msn.com:80'. That is -- + /// the 'default' port can be either omitted or explicit. Since we don't have a way to map a scheme + /// to it's default port, we don't have a way to know these are equal. This is just one of a class of + /// issues with regard to scheme-specific behavior. + /// + class uri + { + public: + + /// + /// The various components of a URI. This enum is used to indicate which + /// URI component is being encoded to the encode_uri_component. This allows + /// specific encoding to be performed. + /// + /// Scheme and port don't allow '%' so they don't need to be encoded. + /// + class components + { + public: + enum component + { + user_info, + host, + path, + query, + fragment, + full_uri + }; + }; + + /// + /// Encodes a URI component according to RFC 3986. + /// Note if a full URI is specified instead of an individual URI component all + /// characters not in the unreserved set are escaped. + /// + /// The URI as a string. + /// The encoded string. + _ASYNCRTIMP static xsapi_internal_string __cdecl encode_uri(const xsapi_internal_string &raw, uri::components::component = components::full_uri); + + /// + /// Encodes a string by converting all characters except for RFC 3986 unreserved characters to their + /// hexadecimal representation. + /// + /// The UTF-8 string data. + /// The encoded string. + _ASYNCRTIMP static xsapi_internal_string __cdecl encode_data_string(const xsapi_internal_string &utf8data); + + /// + /// Decodes an encoded string. + /// + /// The URI as a string. + /// The decoded string. + _ASYNCRTIMP static xsapi_internal_string __cdecl decode(const xsapi_internal_string &encoded); + + /// + /// Splits a path into its hierarchical components. + /// + /// The path as a string + /// A std::vector<xsapi_internal_string> containing the segments in the path. + _ASYNCRTIMP static std::vector __cdecl split_path(const xsapi_internal_string &path); + + /// + /// Splits a query into its key-value components. + /// + /// The query string + /// A std::map<xsapi_internal_string, xsapi_internal_string> containing the key-value components of the query. + _ASYNCRTIMP static std::map __cdecl split_query(const xsapi_internal_string &query); + + /// + /// Validates a string as a URI. + /// + /// The URI string to be validated. + /// true if the given string represents a valid URI, false otherwise. + _ASYNCRTIMP static bool __cdecl validate(const xsapi_internal_string &uri_string); + + /// + /// Creates an empty uri + /// + uri() { m_uri = "/";}; + + /// + /// Creates a URI from the given URI components. + /// + /// A URI components object to create the URI instance. + _ASYNCRTIMP uri(const details::uri_components &components); + + /// + /// Creates a URI from the given encoded string. This will throw an exception if the string + /// does not contain a valid URI. Use uri::validate if processing user-input. + /// + /// A pointer to an encoded string to create the URI instance. + _ASYNCRTIMP uri(const char *uri_string); + + /// + /// Creates a URI from the given encoded string. This will throw an exception if the string + /// does not contain a valid URI. Use uri::validate if processing user-input. + /// + /// An encoded URI string to create the URI instance. + _ASYNCRTIMP uri(const xsapi_internal_string &uri_string); + + /// + /// Copy constructor. + /// + uri(const uri &other) : + m_uri(other.m_uri), + m_components(other.m_components) + {} + + /// + /// Copy assignment operator. + /// + uri & operator=(const uri &other) + { + if (this != &other) + { + m_uri = other.m_uri; + m_components = other.m_components; + } + return *this; + } + + /// + /// Move constructor. + /// + uri(uri &&other) CPPREST_NOEXCEPT : + m_uri(std::move(other.m_uri)), + m_components(std::move(other.m_components)) + {} + + /// + /// Move assignment operator + /// + uri & operator=(uri &&other) CPPREST_NOEXCEPT + { + if (this != &other) + { + m_uri = std::move(other.m_uri); + m_components = std::move(other.m_components); + } + return *this; + } + + /// + /// Get the scheme component of the URI as an encoded string. + /// + /// The URI scheme as a string. + const xsapi_internal_string &scheme() const { return m_components.m_scheme; } + + /// + /// Get the user information component of the URI as an encoded string. + /// + /// The URI user information as a string. + const xsapi_internal_string &user_info() const { return m_components.m_user_info; } + + /// + /// Get the host component of the URI as an encoded string. + /// + /// The URI host as a string. + const xsapi_internal_string &host() const { return m_components.m_host; } + + /// + /// Get the port component of the URI. Returns -1 if no port is specified. + /// + /// The URI port as an integer. + int port() const { return m_components.m_port; } + + /// + /// Get the path component of the URI as an encoded string. + /// + /// The URI path as a string. + const xsapi_internal_string &path() const { return m_components.m_path; } + + /// + /// Get the query component of the URI as an encoded string. + /// + /// The URI query as a string. + const xsapi_internal_string &query() const { return m_components.m_query; } + + /// + /// Get the fragment component of the URI as an encoded string. + /// + /// The URI fragment as a string. + const xsapi_internal_string &fragment() const { return m_components.m_fragment; } + + /// + /// Creates a new uri object with the same authority portion as this one, omitting the resource and query portions. + /// + /// The new uri object with the same authority. + _ASYNCRTIMP uri authority() const; + + /// + /// Gets the path, query, and fragment portion of this uri, which may be empty. + /// + /// The new URI object with the path, query and fragment portion of this URI. + _ASYNCRTIMP uri resource() const; + + /// + /// An empty URI specifies no components, and serves as a default value + /// + bool is_empty() const + { + return this->m_uri.empty() || this->m_uri == "/"; + } + + /// + /// A loopback URI is one which refers to a hostname or ip address with meaning only on the local machine. + /// + /// + /// Examples include "locahost", or ip addresses in the loopback range (127.0.0.0/24). + /// + /// true if this URI references the local host, false otherwise. + bool is_host_loopback() const + { + return !is_empty() && ((host() == "localhost") || (host().size() > 4 && host().substr(0,4) == "127.")); + } + + /// + /// A wildcard URI is one which refers to all hostnames that resolve to the local machine (using the * or +) + /// + /// + /// http://*:80 + /// + bool is_host_wildcard() const + { + return !is_empty() && (this->host() == "*" || this->host() == "+"); + } + + /// + /// A portable URI is one with a hostname that can be resolved globally (used from another machine). + /// + /// true if this URI can be resolved globally (used from another machine), false otherwise. + /// + /// The hostname "localhost" is a reserved name that is guaranteed to resolve to the local machine, + /// and cannot be used for inter-machine communication. Likewise the hostnames "*" and "+" on Windows + /// represent wildcards, and do not map to a resolvable address. + /// + bool is_host_portable() const + { + return !(is_empty() || is_host_loopback() || is_host_wildcard()); + } + + /// + /// A default port is one where the port is unspecified, and will be determined by the operating system. + /// The choice of default port may be dictated by the scheme (http -> 80) or not. + /// + /// true if this URI instance has a default port, false otherwise. + bool is_port_default() const + { + return !is_empty() && this->port() == 0; + } + + /// + /// An "authority" URI is one with only a scheme, optional userinfo, hostname, and (optional) port. + /// + /// true if this is an "authority" URI, false otherwise. + bool is_authority() const + { + return !is_empty() && is_path_empty() && query().empty() && fragment().empty(); + } + + /// + /// Returns whether the other URI has the same authority as this one + /// + /// The URI to compare the authority with. + /// true if both the URI's have the same authority, false otherwise. + bool has_same_authority(const uri &other) const + { + return !is_empty() && this->authority() == other.authority(); + } + + /// + /// Returns whether the path portion of this URI is empty + /// + /// true if the path portion of this URI is empty, false otherwise. + bool is_path_empty() const + { + return path().empty() || path() == "/"; + } + + /// + /// Returns the full (encoded) URI as a string. + /// + /// The full encoded URI string. + xsapi_internal_string to_string() const + { + return m_uri; + } + + _ASYNCRTIMP bool operator == (const uri &other) const; + + bool operator < (const uri &other) const + { + return m_uri < other.m_uri; + } + + bool operator != (const uri &other) const + { + return !(this->operator == (other)); + } + + friend class uri_builder; + + // Encodes all characters not in given set determined by given function. + _ASYNCRTIMP static xsapi_internal_string __cdecl encode_impl(const xsapi_internal_string& raw, const std::function& should_encode); + + xsapi_internal_string m_uri; + details::uri_components m_components; + }; + +} // namespace web + +} } } \ No newline at end of file diff --git a/Source/Shared/HookedUri/details/asyncrt_utils.hpp b/Source/Shared/HookedUri/details/asyncrt_utils.hpp new file mode 100644 index 00000000..0121d5d8 --- /dev/null +++ b/Source/Shared/HookedUri/details/asyncrt_utils.hpp @@ -0,0 +1,1141 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Utilities +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#if defined(_WIN32) +#if HC_PLATFORM != HC_PLATFORM_XDK +#include +#endif +#else // _WIN32 +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif +// TODO 1808 #include +// #include +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +#endif // _WIN32 + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 26444 ) // ignore various unnamed objects +#pragma warning( disable : 26498 ) // ignore eof warning +#pragma warning( disable : 26812 ) // enum instead of enum class +#endif + +// Could use C++ standard library if not __GLIBCXX__, +// For testing purposes we just the handwritten on all platforms. +#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) +#include +#endif + +using namespace xbox::services::cppresturi::web; +using namespace xbox::services::cppresturi::utility; +using namespace xbox::services::cppresturi::utility::conversions; + + +namespace xbox { namespace services { namespace cppresturi { + +namespace utility +{ + +namespace details +{ + +#if !defined(ANDROID) && !defined(__ANDROID__) +std::once_flag g_c_localeFlag; +std::unique_ptr g_c_locale(nullptr, [](scoped_c_thread_locale::xplat_locale *){}); +scoped_c_thread_locale::xplat_locale scoped_c_thread_locale::c_locale() +{ + std::call_once(g_c_localeFlag, [&]() + { + scoped_c_thread_locale::xplat_locale *clocale = new scoped_c_thread_locale::xplat_locale(); +#ifdef _WIN32 + if (clocale == nullptr) + { + throw std::runtime_error("Unable to create 'C' locale."); + } + *clocale = _create_locale(LC_ALL, "C"); + if (clocale == nullptr || *clocale == nullptr) + { + throw std::runtime_error("Unable to create 'C' locale."); + } + auto deleter = [](scoped_c_thread_locale::xplat_locale *clocale) + { + _free_locale(*clocale); + delete clocale; + }; +#else + *clocale = newlocale(LC_ALL, "C", nullptr); + if (clocale == nullptr || *clocale == nullptr) + { + throw std::runtime_error("Unable to create 'C' locale."); + } + auto deleter = [](scoped_c_thread_locale::xplat_locale *clocale) + { + freelocale(*clocale); + delete clocale; + }; +#endif + g_c_locale = std::unique_ptr(clocale, deleter); + }); + return *g_c_locale; +} +#endif + +#ifdef _WIN32 +scoped_c_thread_locale::scoped_c_thread_locale() + : m_prevLocale(), m_prevThreadSetting(-1) +{ + char *prevLocale = setlocale(LC_ALL, nullptr); + if (prevLocale == nullptr) + { + throw std::runtime_error("Unable to retrieve current locale."); + } + + if (std::strcmp(prevLocale, "C") != 0) + { + m_prevLocale = prevLocale; + m_prevThreadSetting = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + if (m_prevThreadSetting == -1) + { + throw std::runtime_error("Unable to enable per thread locale."); + } + if (setlocale(LC_ALL, "C") == nullptr) + { + _configthreadlocale(m_prevThreadSetting); + throw std::runtime_error("Unable to set locale"); + } + } +} + +scoped_c_thread_locale::~scoped_c_thread_locale() +{ + if (m_prevThreadSetting != -1) + { + setlocale(LC_ALL, m_prevLocale.c_str()); + _configthreadlocale(m_prevThreadSetting); + } +} +#elif (defined(ANDROID) || defined(__ANDROID__)) +scoped_c_thread_locale::scoped_c_thread_locale() {} +scoped_c_thread_locale::~scoped_c_thread_locale() {} +#else +scoped_c_thread_locale::scoped_c_thread_locale() + : m_prevLocale(nullptr) +{ + char *prevLocale = setlocale(LC_ALL, nullptr); + if (prevLocale == nullptr) + { + throw std::runtime_error("Unable to retrieve current locale."); + } + + if (std::strcmp(prevLocale, "C") != 0) + { + m_prevLocale = uselocale(c_locale()); + if (m_prevLocale == nullptr) + { + throw std::runtime_error("Unable to set locale"); + } + } +} + +scoped_c_thread_locale::~scoped_c_thread_locale() +{ + if (m_prevLocale != nullptr) + { + uselocale(m_prevLocale); + } +} +#endif +} + +namespace details +{ + +const std::error_category & platform_category() +{ +#ifdef _WIN32 + return windows_category(); +#else + return linux_category(); +#endif +} + +#ifdef _WIN32 + +// Remove once VS 2013 is no longer supported. +#if _MSC_VER < 1900 +static details::windows_category_impl instance; +#endif +const std::error_category & windows_category() +{ +#if _MSC_VER >= 1900 + static details::windows_category_impl instance; +#endif + return instance; +} + +std::string windows_category_impl::message(int errorCode) const CPPREST_NOEXCEPT +{ +#if 0 // this returns a non-mem hooked string which can't be changed so commenting it out since its not really needed + const size_t buffer_size = 4096; + DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM; + LPCVOID lpSource = NULL; + +#if !defined(__cplusplus_winrt) + if (errorCode >= 12000) + { + dwFlags = FORMAT_MESSAGE_FROM_HMODULE; + lpSource = GetModuleHandleA("winhttp.dll"); // this handle DOES NOT need to be freed + } +#endif + + std::wstring buffer; + buffer.resize(buffer_size); + + const auto result = ::FormatMessageW( + dwFlags, + lpSource, + errorCode, + 0, + &buffer[0], + buffer_size, + NULL); + if (result == 0) + { + std::ostringstream os; + os << "Unable to get an error message for error code: " << errorCode << "."; + return os.str(); + } + + return utility::conversions::to_utf8string(buffer); +#else + UNREFERENCED_PARAMETER(errorCode); + return std::string(); +#endif +} + +std::error_condition windows_category_impl::default_error_condition(int errorCode) const CPPREST_NOEXCEPT +{ + // First see if the STL implementation can handle the mapping for common cases. + const std::error_condition errCondition = std::system_category().default_error_condition(errorCode); + const std::string errConditionMsg = errCondition.message(); + if(_stricmp(errConditionMsg.c_str(), "unknown error") != 0) + { + return errCondition; + } + + switch(errorCode) + { +#ifndef __cplusplus_winrt + case ERROR_WINHTTP_TIMEOUT: + return std::errc::timed_out; + case ERROR_WINHTTP_CANNOT_CONNECT: + return std::errc::host_unreachable; + case ERROR_WINHTTP_CONNECTION_ERROR: + return std::errc::connection_aborted; +#endif + case INET_E_RESOURCE_NOT_FOUND: + case INET_E_CANNOT_CONNECT: + return std::errc::host_unreachable; + case INET_E_CONNECTION_TIMEOUT: + return std::errc::timed_out; + case INET_E_DOWNLOAD_FAILURE: + return std::errc::connection_aborted; + default: + break; + } + + return std::error_condition(errorCode, *this); +} + +#else + +const std::error_category & linux_category() +{ + // On Linux we are using boost error codes which have the exact same + // mapping and are equivalent with std::generic_category error codes. + return std::generic_category(); +} + +#endif + +} + +#define LOW_3BITS 0x7 +#define LOW_4BITS 0xF +#define LOW_5BITS 0x1F +#define LOW_6BITS 0x3F +#define BIT4 0x8 +#define BIT5 0x10 +#define BIT6 0x20 +#define BIT7 0x40 +#define BIT8 0x80 +#define L_SURROGATE_START 0xDC00 +#define L_SURROGATE_END 0xDFFF +#define H_SURROGATE_START 0xD800 +#define H_SURROGATE_END 0xDBFF +#define SURROGATE_PAIR_START 0x10000 + +utf16string conversions::utf8_to_utf16(const std::string &s) +{ +#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) + std::wstring_convert, utf16char> conversion; + return conversion.from_bytes(s); +#else + utf16string dest; + // Save repeated heap allocations, use less than source string size assuming some + // of the characters are not just ASCII and collapse. + dest.reserve(static_cast(static_cast(s.size()) * .70)); + + for (auto src = s.begin(); src != s.end(); ++src) + { + if ((*src & BIT8) == 0) // single byte character, 0x0 to 0x7F + { + dest.push_back(utf16string::value_type(*src)); + } + else + { + unsigned char numContBytes = 0; + uint32_t codePoint; + if ((*src & BIT7) == 0) + { + throw std::range_error("UTF-8 string character can never start with 10xxxxxx"); + } + else if ((*src & BIT6) == 0) // 2 byte character, 0x80 to 0x7FF + { + codePoint = *src & LOW_5BITS; + numContBytes = 1; + } + else if ((*src & BIT5) == 0) // 3 byte character, 0x800 to 0xFFFF + { + codePoint = *src & LOW_4BITS; + numContBytes = 2; + } + else if ((*src & BIT4) == 0) // 4 byte character, 0x10000 to 0x10FFFF + { + codePoint = *src & LOW_3BITS; + numContBytes = 3; + } + else + { + throw std::range_error("UTF-8 string has invalid Unicode code point"); + } + + for (unsigned char i = 0; i < numContBytes; ++i) + { + if (++src == s.end()) + { + throw std::range_error("UTF-8 string is missing bytes in character"); + } + if ((*src & BIT8) == 0 || (*src & BIT7) != 0) + { + throw std::range_error("UTF-8 continuation byte is missing leading byte"); + } + codePoint <<= 6; + codePoint |= *src & LOW_6BITS; + } + + if (codePoint >= SURROGATE_PAIR_START) + { + // In UTF-16 U+10000 to U+10FFFF are represented as two 16-bit code units, surrogate pairs. + // - 0x10000 is subtracted from the code point + // - high surrogate is 0xD800 added to the top ten bits + // - low surrogate is 0xDC00 added to the low ten bits + codePoint -= SURROGATE_PAIR_START; + dest.push_back(utf16string::value_type((codePoint >> 10) | H_SURROGATE_START)); + dest.push_back(utf16string::value_type((codePoint & 0x3FF) | L_SURROGATE_START)); + } + else + { + // In UTF-16 U+0000 to U+D7FF and U+E000 to U+FFFF are represented exactly as the Unicode code point value. + // U+D800 to U+DFFF are not valid characters, for simplicity we assume they are not present but will encode + // them if encountered. + dest.push_back(utf16string::value_type(codePoint)); + } + } + } + return dest; +#endif +} + +xsapi_internal_string conversions::utf16_to_utf8_internal(const xsapi_internal_wstring &w) +{ + #if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) + std::wstring_convert, utf16char> conversion; + return conversion.to_bytes(w); + #else + xsapi_internal_string dest; + dest.reserve(w.size()); + for (auto src = w.begin(); src != w.end(); ++src) + { + // Check for high surrogate. + if (*src >= H_SURROGATE_START && *src <= H_SURROGATE_END) + { + const auto highSurrogate = *src++; + if (src == w.end()) + { + throw std::range_error("UTF-16 string is missing low surrogate"); + } + const auto lowSurrogate = *src; + if (lowSurrogate < L_SURROGATE_START || lowSurrogate > L_SURROGATE_END) + { + throw std::range_error("UTF-16 string has invalid low surrogate"); + } + + // To get from surrogate pair to Unicode code point: + // - subract 0xD800 from high surrogate, this forms top ten bits + // - subract 0xDC00 from low surrogate, this forms low ten bits + // - add 0x10000 + // Leaves a code point in U+10000 to U+10FFFF range. + uint32_t codePoint = highSurrogate - H_SURROGATE_START; + codePoint <<= 10; + codePoint |= lowSurrogate - L_SURROGATE_START; + codePoint += SURROGATE_PAIR_START; + + // 4 bytes need using 21 bits + dest.push_back(char((codePoint >> 18) | 0xF0)); // leading 3 bits + dest.push_back(char(((codePoint >> 12) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char(((codePoint >> 6) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char((codePoint & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else + { + if (*src <= 0x7F) // single byte character + { + dest.push_back(static_cast(*src)); + } + else if (*src <= 0x7FF) // 2 bytes needed (11 bits used) + { + dest.push_back(char((*src >> 6) | 0xC0)); // leading 5 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else // 3 bytes needed (16 bits used) + { + dest.push_back(char((*src >> 12) | 0xE0)); // leading 4 bits + dest.push_back(char(((*src >> 6) & LOW_6BITS) | BIT8)); // middle 6 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + } + } + + return dest; + #endif +} + +std::string conversions::utf16_to_utf8(const utf16string&w) +{ +#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) + std::wstring_convert, utf16char> conversion; + return conversion.to_bytes(w); +#else + std::string dest; + dest.reserve(w.size()); + for (auto src = w.begin(); src != w.end(); ++src) + { + // Check for high surrogate. + if (*src >= H_SURROGATE_START && *src <= H_SURROGATE_END) + { + const auto highSurrogate = *src++; + if (src == w.end()) + { + throw std::range_error("UTF-16 string is missing low surrogate"); + } + const auto lowSurrogate = *src; + if (lowSurrogate < L_SURROGATE_START || lowSurrogate > L_SURROGATE_END) + { + throw std::range_error("UTF-16 string has invalid low surrogate"); + } + + // To get from surrogate pair to Unicode code point: + // - subract 0xD800 from high surrogate, this forms top ten bits + // - subract 0xDC00 from low surrogate, this forms low ten bits + // - add 0x10000 + // Leaves a code point in U+10000 to U+10FFFF range. + uint32_t codePoint = highSurrogate - H_SURROGATE_START; + codePoint <<= 10; + codePoint |= lowSurrogate - L_SURROGATE_START; + codePoint += SURROGATE_PAIR_START; + + // 4 bytes need using 21 bits + dest.push_back(char((codePoint >> 18) | 0xF0)); // leading 3 bits + dest.push_back(char(((codePoint >> 12) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char(((codePoint >> 6) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char((codePoint & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else + { + if (*src <= 0x7F) // single byte character + { + dest.push_back(static_cast(*src)); + } + else if (*src <= 0x7FF) // 2 bytes needed (11 bits used) + { + dest.push_back(char((*src >> 6) | 0xC0)); // leading 5 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else // 3 bytes needed (16 bits used) + { + dest.push_back(char((*src >> 12) | 0xE0)); // leading 4 bits + dest.push_back(char(((*src >> 6) & LOW_6BITS) | BIT8)); // middle 6 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + } + } + + return dest; +#endif +} + +utf16string conversions::usascii_to_utf16(const std::string &s) +{ + // Ascii is a subset of UTF-8 so just convert to UTF-16 + return utf8_to_utf16(s); +} + +xsapi_internal_wstring conversions::latin1_to_utf16_internal(const xsapi_internal_string &s) +{ + // Latin1 is the first 256 code points in Unicode. + // In UTF-16 encoding each of these is represented as exactly the numeric code point. + xsapi_internal_wstring dest; + dest.resize(s.size()); + for (size_t i = 0; i < s.size(); ++i) + { + dest[i] = utf16char(static_cast(s[i])); + } + return dest; +} + +xsapi_internal_string conversions::latin1_to_utf8_internal(const xsapi_internal_string &s) +{ + return utf16_to_utf8_internal(latin1_to_utf16_internal(s)); +} + +utility::string_t conversions::to_string_t(utf16string &&s) +{ +#ifdef _UTF16_STRINGS + return std::move(s); +#else + return utf16_to_utf8(std::move(s)); +#endif +} + +utility::string_t conversions::to_string_t(std::string &&s) +{ +#ifdef _UTF16_STRINGS + return utf8_to_utf16(std::move(s)); +#else + return std::move(s); +#endif +} + +utility::string_t conversions::to_string_t(const utf16string &s) +{ +#ifdef _UTF16_STRINGS + return s; +#else + return utf16_to_utf8(s); +#endif +} + +utility::string_t conversions::to_string_t(const std::string &s) +{ +#ifdef _UTF16_STRINGS + return utf8_to_utf16(s); +#else + return s; +#endif +} + +xsapi_internal_string conversions::to_utf8string_internal(xsapi_internal_string value) { return value; } + +xsapi_internal_string conversions::to_utf8string_internal(const xsapi_internal_wstring &value) +{ + return utf16_to_utf8_internal(value); +} + +utf16string conversions::to_utf16string(const std::string &value) { return utf8_to_utf16(value); } + +utf16string conversions::to_utf16string(utf16string value) { return value; } + +#ifndef _WIN32 +datetime datetime::timeval_to_datetime(const timeval &time) +{ + const uint64_t epoch_offset = 11644473600LL; // diff between windows and unix epochs (seconds) + uint64_t result = epoch_offset + time.tv_sec; + result *= _secondTicks; // convert to 10e-7 + result += time.tv_usec * 10; // convert and add microseconds, 10e-6 to 10e-7 + return datetime(result); +} +#endif + +static bool is_digit(utility::char_t c) { return c >= _XPLATSTR('0') && c <= _XPLATSTR('9'); } + +datetime datetime::utc_now() +{ +#ifdef _WIN32 + ULARGE_INTEGER largeInt; + FILETIME fileTime; + GetSystemTimeAsFileTime(&fileTime); + + largeInt.LowPart = fileTime.dwLowDateTime; + largeInt.HighPart = fileTime.dwHighDateTime; + + return datetime(largeInt.QuadPart); +#else //LINUX + timeval time {}; + gettimeofday(&time, nullptr); + return timeval_to_datetime(time); +#endif +} + +xsapi_internal_string datetime::to_string_internal(date_format format) const +{ +#ifdef _WIN32 + int status; + + ULARGE_INTEGER largeInt; + largeInt.QuadPart = m_interval; + + FILETIME ft; + ft.dwHighDateTime = largeInt.HighPart; + ft.dwLowDateTime = largeInt.LowPart; + + SYSTEMTIME systemTime; + if (!FileTimeToSystemTime((const FILETIME *)&ft, &systemTime)) + { + throw utility::details::create_system_error(GetLastError()); + } + + xsapi_internal_wostringstream outStream; + outStream.imbue(std::locale::classic()); + + if (format == RFC_1123) + { +#if _WIN32_WINNT < _WIN32_WINNT_VISTA + TCHAR dateStr[18] = {0}; + status = GetDateFormat(LOCALE_INVARIANT, 0, &systemTime, __TEXT("ddd',' dd MMM yyyy"), dateStr, sizeof(dateStr) / sizeof(TCHAR)); +#else + wchar_t dateStr[18] = {0}; + status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"ddd',' dd MMM yyyy", dateStr, sizeof(dateStr) / sizeof(wchar_t), NULL); +#endif // _WIN32_WINNT < _WIN32_WINNT_VISTA + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + +#if _WIN32_WINNT < _WIN32_WINNT_VISTA + TCHAR timeStr[10] = {0}; + status = GetTimeFormat(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, __TEXT("HH':'mm':'ss"), timeStr, sizeof(timeStr) / sizeof(TCHAR)); +#else + wchar_t timeStr[10] = {0}; + status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, sizeof(timeStr) / sizeof(wchar_t)); +#endif // _WIN32_WINNT < _WIN32_WINNT_VISTA + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + outStream << dateStr << " " << timeStr << " " << "GMT"; + } + else if (format == ISO_8601) + { + const size_t buffSize = 64; +#if _WIN32_WINNT < _WIN32_WINNT_VISTA + TCHAR dateStr[buffSize] = {0}; + status = GetDateFormat(LOCALE_INVARIANT, 0, &systemTime, __TEXT("yyyy-MM-dd"), dateStr, buffSize); +#else + wchar_t dateStr[buffSize] = {0}; + status = GetDateFormatEx(LOCALE_NAME_INVARIANT, 0, &systemTime, L"yyyy-MM-dd", dateStr, buffSize, NULL); +#endif // _WIN32_WINNT < _WIN32_WINNT_VISTA + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + +#if _WIN32_WINNT < _WIN32_WINNT_VISTA + TCHAR timeStr[buffSize] = {0}; + status = GetTimeFormat(LOCALE_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, __TEXT("HH':'mm':'ss"), timeStr, buffSize); +#else + wchar_t timeStr[buffSize] = {0}; + status = GetTimeFormatEx(LOCALE_NAME_INVARIANT, TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, &systemTime, L"HH':'mm':'ss", timeStr, buffSize); +#endif // _WIN32_WINNT < _WIN32_WINNT_VISTA + if (status == 0) + { + throw utility::details::create_system_error(GetLastError()); + } + + outStream << dateStr << "T" << timeStr; + uint64_t frac_sec = largeInt.QuadPart % _secondTicks; + if (frac_sec > 0) + { + // Append fractional second, which is a 7-digit value with no trailing zeros + // This way, '1200' becomes '00012' + char buf[9] = { 0 }; + sprintf_s(buf, sizeof(buf), ".%07ld", (long int)frac_sec); + // trim trailing zeros + for (int i = 7; buf[i] == '0'; i--) buf[i] = '\0'; + outStream << buf; + } + outStream << "Z"; + } + + return conversions::to_utf8string_internal(outStream.str()); +#else //LINUX + uint64_t input = m_interval; + uint64_t frac_sec = input % _secondTicks; + input /= _secondTicks; // convert to seconds + time_t time = (time_t)input - (time_t)11644473600LL;// diff between windows and unix epochs (seconds) + + struct tm datetime; + gmtime_r(&time, &datetime); + + const int max_dt_length = 64; + char output[max_dt_length+1] = {0}; + + if (format != RFC_1123 && frac_sec > 0) + { + // Append fractional second, which is a 7-digit value with no trailing zeros + // This way, '1200' becomes '00012' + char buf[9] = { 0 }; + snprintf(buf, sizeof(buf), ".%07ld", (long int)frac_sec); + // trim trailing zeros + for (int i = 7; buf[i] == '0'; i--) buf[i] = '\0'; + // format the datetime into a separate buffer + char datetime_str[max_dt_length+1] = {0}; + strftime(datetime_str, sizeof(datetime_str), "%Y-%m-%dT%H:%M:%S", &datetime); + // now print this buffer into the output buffer + snprintf(output, sizeof(output), "%s%sZ", datetime_str, buf); + } + else + { + strftime(output, sizeof(output), + format == RFC_1123 ? "%a, %d %b %Y %H:%M:%S GMT" : "%Y-%m-%dT%H:%M:%SZ", + &datetime); + } + + return xsapi_internal_string(output); +#endif +} + +#ifdef _WIN32 +bool datetime::system_type_to_datetime(void* pvsysTime, uint64_t seconds, datetime * pdt) +{ + SYSTEMTIME* psysTime = (SYSTEMTIME*)pvsysTime; + FILETIME fileTime; + + if (SystemTimeToFileTime(psysTime, &fileTime)) + { + ULARGE_INTEGER largeInt; + largeInt.LowPart = fileTime.dwLowDateTime; + largeInt.HighPart = fileTime.dwHighDateTime; + + // Add hundredths of nanoseconds + largeInt.QuadPart += seconds; + + *pdt = datetime(largeInt.QuadPart); + return true; + } + return false; +} +#endif + +// Take a string that represents a fractional second and return the number of ticks +// This is equivalent to doing atof on the string and multiplying by 10000000, +// but does not lose precision +template +uint64_t timeticks_from_second(StringIterator begin, StringIterator end) +{ + int size = (int)(end - begin); + _ASSERTE(begin[0] == U('.')); + uint64_t ufrac_second = 0; + for (int i = 1; i <= 7; ++i) + { + ufrac_second *= 10; + int add = i < size ? begin[i] - U('0') : 0; + ufrac_second += add; + } + return ufrac_second; +} + +void extract_fractional_second(const utility::string_t& dateString, utility::string_t& resultString, uint64_t& ufrac_second) +{ + resultString = dateString; + // First, the string must be strictly longer than 2 characters, and the trailing character must be 'Z' + if (resultString.size() > 2 && resultString[resultString.size() - 1] == U('Z')) + { + // Second, find the last non-digit by scanning the string backwards + auto last_non_digit = std::find_if_not(resultString.rbegin() + 1, resultString.rend(), is_digit); + if (last_non_digit < resultString.rend() - 1) + { + // Finally, make sure the last non-digit is a dot: + auto last_dot = last_non_digit.base() - 1; + if (*last_dot == U('.')) + { + // Got it! Now extract the fractional second + auto last_before_Z = std::end(resultString) - 1; + ufrac_second = timeticks_from_second(last_dot, last_before_Z); + // And erase it from the string + resultString.erase(last_dot, last_before_Z); + } + } + } +} + +datetime datetime::from_string(const utility::string_t& dateString, date_format format) +{ + // avoid floating point math to preserve precision + uint64_t ufrac_second = 0; + +#ifdef _WIN32 + datetime result; + if (format == RFC_1123) + { + SYSTEMTIME sysTime = {0}; + + std::wstring month(3, L'\0'); + std::wstring unused(3, L'\0'); + + const wchar_t * formatString = L"%3c, %2d %3c %4d %2d:%2d:%2d %3c"; + auto n = swscanf_s(dateString.c_str(), formatString, + unused.data(), unused.size(), + &sysTime.wDay, + month.data(), month.size(), + &sysTime.wYear, + &sysTime.wHour, + &sysTime.wMinute, + &sysTime.wSecond, + unused.data(), unused.size()); + + if (n == 8) + { + std::wstring monthnames[12] = {L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"}; + auto loc = std::find_if(monthnames, monthnames+12, [&month](const std::wstring& m) { return m == month;}); + + if (loc != monthnames+12) + { + sysTime.wMonth = (short) ((loc - monthnames) + 1); + if (system_type_to_datetime(&sysTime, ufrac_second, &result)) + { + return result; + } + } + } + } + else if (format == ISO_8601) + { + // Unlike FILETIME, SYSTEMTIME does not have enough precision to hold seconds in 100 nanosecond + // increments. Therefore, start with seconds and milliseconds set to 0, then add them separately + + // Try to extract the fractional second from the timestamp + utility::string_t input; + extract_fractional_second(dateString, input, ufrac_second); + { + SYSTEMTIME sysTime = { 0 }; + const wchar_t * formatString = L"%4d-%2d-%2dT%2d:%2d:%2dZ"; + auto n = swscanf_s(input.c_str(), formatString, + &sysTime.wYear, + &sysTime.wMonth, + &sysTime.wDay, + &sysTime.wHour, + &sysTime.wMinute, + &sysTime.wSecond); + + if (n == 3 || n == 6) + { + if (system_type_to_datetime(&sysTime, ufrac_second, &result)) + { + return result; + } + } + } + { + SYSTEMTIME sysTime = {0}; + DWORD date = 0; + + const wchar_t * formatString = L"%8dT%2d:%2d:%2dZ"; + auto n = swscanf_s(input.c_str(), formatString, + &date, + &sysTime.wHour, + &sysTime.wMinute, + &sysTime.wSecond); + + if (n == 1 || n == 4) + { + sysTime.wDay = date % 100; + date /= 100; + sysTime.wMonth = date % 100; + date /= 100; + sysTime.wYear = (WORD)date; + + if (system_type_to_datetime(&sysTime, ufrac_second, &result)) + { + return result; + } + } + } + { + SYSTEMTIME sysTime = {0}; + GetSystemTime(&sysTime); // Fill date portion with today's information + sysTime.wSecond = 0; + sysTime.wMilliseconds = 0; + + const wchar_t * formatString = L"%2d:%2d:%2dZ"; + auto n = swscanf_s(input.c_str(), formatString, + &sysTime.wHour, + &sysTime.wMinute, + &sysTime.wSecond); + + if (n == 3) + { + if (system_type_to_datetime(&sysTime, ufrac_second, &result)) + { + return result; + } + } + } + } + + return datetime(); +#else + std::string input(dateString); + + struct tm output = tm(); + + if (format == RFC_1123) + { + strptime(input.data(), "%a, %d %b %Y %H:%M:%S GMT", &output); + } + else + { + // Try to extract the fractional second from the timestamp + utility::string_t input; + extract_fractional_second(dateString, input, ufrac_second); + + auto result = strptime(input.data(), "%Y-%m-%dT%H:%M:%SZ", &output); + + if (result == nullptr) + { + result = strptime(input.data(), "%Y%m%dT%H:%M:%SZ", &output); + } + if (result == nullptr) + { + // Fill the date portion with the epoch, + // strptime will do the rest + memset(&output, 0, sizeof(struct tm)); + output.tm_year = 70; + output.tm_mon = 1; + output.tm_mday = 1; + result = strptime(input.data(), "%H:%M:%SZ", &output); + } + if (result == nullptr) + { + result = strptime(input.data(), "%Y-%m-%d", &output); + } + if (result == nullptr) + { + result = strptime(input.data(), "%Y%m%d", &output); + } + if (result == nullptr) + { + return datetime(); + } + } + +#if (defined(ANDROID) || defined(__ANDROID__)) + // HACK: The (nonportable?) POSIX function timegm is not available in + // bionic. As a workaround[1][2], we set the C library timezone to + // UTC, call mktime, then set the timezone back. However, the C + // environment is fundamentally a shared global resource and thread- + // unsafe. We can protect our usage here, however any other code might + // manipulate the environment at the same time. + // + // [1] http://linux.die.net/man/3/timegm + // [2] http://www.gnu.org/software/libc/manual/html_node/Broken_002ddown-Time.html + time_t time; + + static std::mutex env_var_lock; + { + std::lock_guard lock(env_var_lock); + std::string prev_env; + auto prev_env_cstr = getenv("TZ"); + if (prev_env_cstr != nullptr) + { + prev_env = prev_env_cstr; + } + setenv("TZ", "UTC", 1); + + time = mktime(&output); + + if (prev_env_cstr) + { + setenv("TZ", prev_env.c_str(), 1); + } + else + { + unsetenv("TZ"); + } + tzset(); + } +#else + time_t time = timegm(&output); +#endif + struct timeval tv = timeval(); + tv.tv_sec = time; + auto result = timeval_to_datetime(tv); + + // fractional seconds are already in correct format so just add them. + result = result + ufrac_second; + return result; +#endif +} + +/// +/// Converts a timespan/interval in seconds to xml duration string as specified by +/// http://www.w3.org/TR/xmlschema-2/#duration +/// +utility::string_t timespan::seconds_to_xml_duration(utility::seconds durationSecs) +{ + auto numSecs = durationSecs.count(); + + // Find the number of minutes + auto numMins = numSecs / 60; + if (numMins > 0) + { + numSecs = numSecs % 60; + } + + // Hours + auto numHours = numMins / 60; + if (numHours > 0) + { + numMins = numMins % 60; + } + + // Days + auto numDays = numHours / 24; + if (numDays > 0) + { + numHours = numHours % 24; + } + + // The format is: + // PdaysDThoursHminutesMsecondsS + utility::ostringstream_t oss; + oss.imbue(std::locale::classic()); + + oss << _XPLATSTR("P"); + if (numDays > 0) + { + oss << numDays << _XPLATSTR("D"); + } + + oss << _XPLATSTR("T"); + + if (numHours > 0) + { + oss << numHours << _XPLATSTR("H"); + } + + if (numMins > 0) + { + oss << numMins << _XPLATSTR("M"); + } + + if (numSecs > 0) + { + oss << numSecs << _XPLATSTR("S"); + } + + return oss.str(); +} + +utility::seconds timespan::xml_duration_to_seconds(const utility::string_t ×panString) +{ + // The format is: + // PnDTnHnMnS + // if n == 0 then the field could be omitted + // The final S could be omitted + + int64_t numSecs = 0; + + utility::istringstream_t is(timespanString); + is.imbue(std::locale::classic()); + auto eof = std::char_traits::eof(); + + std::basic_istream::int_type c; + c = is.get(); // P + + while (c != eof) + { + int val = 0; + c = is.get(); + + while (is_digit((utility::char_t)c)) + { + val = val * 10 + (c - L'0'); + c = is.get(); + + if (c == '.') + { + // decimal point is not handled + do { c = is.get(); } while(is_digit((utility::char_t)c)); + } + } + + if (c == L'D') numSecs += static_cast(val) * 24 * 3600; // days + if (c == L'H') numSecs += static_cast(val) * 3600; // Hours + if (c == L'M') numSecs += static_cast(val) * 60; // Minutes + if (c == L'S' || c == eof) + { + numSecs += val; // seconds + break; + } + } + + return utility::seconds(numSecs); +} + +const utility::string_t nonce_generator::c_allowed_chars(_XPLATSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); + +utility::string_t nonce_generator::generate() +{ + std::uniform_int_distribution<> distr(0, static_cast(c_allowed_chars.length() - 1)); + utility::string_t result; + result.reserve(length()); + std::generate_n(std::back_inserter(result), length(), [&]() { return c_allowed_chars[distr(m_random)]; } ); + return result; +} + + +} + +} } } + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif diff --git a/Source/Shared/HookedUri/details/basic_types.h b/Source/Shared/HookedUri/details/basic_types.h new file mode 100644 index 00000000..4ec5bd2d --- /dev/null +++ b/Source/Shared/HookedUri/details/basic_types.h @@ -0,0 +1,127 @@ +/*** +* Copyright (C) Microsoft. All rights reserved. +* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +* +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Platform-dependent type definitions +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include +#include +#include +#include +#include "HookedUri/details/cpprest_compat.h" +#include "pplx/pplxtasks.h" + +#ifndef _WIN32 +# define __STDC_LIMIT_MACROS +# include +#else +#include +#endif + +namespace xbox { namespace services { namespace cppresturi { + +namespace utility +{ + +#ifdef _WIN32 +#define _UTF16_STRINGS +#endif + +// We should be using a 64-bit size type for most situations that do +// not involve specifying the size of a memory allocation or buffer. +typedef uint64_t size64_t; + +#ifdef _UTF16_STRINGS +// +// On Windows, all strings are wide +// +typedef wchar_t char_t ; +typedef std::wstring string_t; +#define _XPLATSTR(x) L ## x +typedef std::wostringstream ostringstream_t; +typedef std::wofstream ofstream_t; +typedef std::wostream ostream_t; +typedef std::wistream istream_t; +typedef std::wifstream ifstream_t; +typedef std::wistringstream istringstream_t; +typedef std::wstringstream stringstream_t; +#define ucout std::wcout +#define ucin std::wcin +#define ucerr std::wcerr +#else +// +// On POSIX platforms, all strings are narrow +// +typedef char char_t; +typedef std::string string_t; +#define _XPLATSTR(x) x +typedef std::ostringstream ostringstream_t; +typedef std::ofstream ofstream_t; +typedef std::ostream ostream_t; +typedef std::istream istream_t; +typedef std::ifstream ifstream_t; +typedef std::istringstream istringstream_t; +typedef std::stringstream stringstream_t; +#define ucout std::cout +#define ucin std::cin +#define ucerr std::cerr +#endif // endif _UTF16_STRINGS + +#ifndef _TURN_OFF_PLATFORM_STRING +#define U(x) _XPLATSTR(x) +#endif // !_TURN_OFF_PLATFORM_STRING + +}// namespace utility + +} } } + +typedef char utf8char; +typedef std::string utf8string; +typedef std::stringstream utf8stringstream; +typedef std::ostringstream utf8ostringstream; +typedef std::ostream utf8ostream; +typedef std::istream utf8istream; +typedef std::istringstream utf8istringstream; + +#ifdef _UTF16_STRINGS +typedef wchar_t utf16char; +typedef std::wstring utf16string; +typedef std::wstringstream utf16stringstream; +typedef std::wostringstream utf16ostringstream; +typedef std::wostream utf16ostream; +typedef std::wistream utf16istream; +typedef std::wistringstream utf16istringstream; +#else +typedef char16_t utf16char; +typedef std::u16string utf16string; +typedef std::basic_stringstream utf16stringstream; +typedef std::basic_ostringstream utf16ostringstream; +typedef std::basic_ostream utf16ostream; +typedef std::basic_istream utf16istream; +typedef std::basic_istringstream utf16istringstream; +#endif + + +#if defined(_WIN32) +// Include on everything except Windows Desktop ARM, unless explicitly excluded. +#if !defined(CPPREST_EXCLUDE_WEBSOCKETS) +#if defined(WINAPI_FAMILY) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_M_ARM) +#define CPPREST_EXCLUDE_WEBSOCKETS +#endif +#else +#if defined(_M_ARM) +#define CPPREST_EXCLUDE_WEBSOCKETS +#endif +#endif +#endif +#endif diff --git a/Source/Shared/HookedUri/details/cpprest_compat.h b/Source/Shared/HookedUri/details/cpprest_compat.h new file mode 100644 index 00000000..79ef836e --- /dev/null +++ b/Source/Shared/HookedUri/details/cpprest_compat.h @@ -0,0 +1,97 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Standard macros and definitions. +* This header has minimal dependency on windows headers and is safe for use in the public API +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#if defined(_WIN32) // Settings specific to Windows + +#if _MSC_VER >= 1900 +#define CPPREST_NOEXCEPT noexcept +#else +#define CPPREST_NOEXCEPT +#endif + +#define CASABLANCA_UNREFERENCED_PARAMETER(x) (x) + +#include + +#else // End settings specific to Windows + +// Settings common to all but Windows + +#define __declspec(x) __attribute__ ((x)) +#define dllimport +#define novtable /* no novtable equivalent */ +#define __assume(x) do { if (!(x)) __builtin_unreachable(); } while (false) +#define CASABLANCA_UNREFERENCED_PARAMETER(x) (void)x +#define CPPREST_NOEXCEPT noexcept + +#include +#define _ASSERTE(x) assert(x) + +// No SAL on non Windows platforms +#include "HookedUri/details/nosal.h" + +#if not defined __cdecl +#if defined cdecl +#define __cdecl __attribute__ ((cdecl)) +#else +#define __cdecl +#endif + +#if defined(__ANDROID__) +// This is needed to disable the use of __thread inside the boost library. +// Android does not support thread local storage -- if boost is included +// without this macro defined, it will create references to __tls_get_addr +// which (while able to link) will not be available at runtime and prevent +// the .so from loading. +#define BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION +#endif + +#ifdef __clang__ +#include +#endif + +#endif // defined(__APPLE__) + +#endif + + +#ifdef _NO_ASYNCRTIMP +#define _ASYNCRTIMP +#else +#ifdef _ASYNCRT_EXPORT +#define _ASYNCRTIMP __declspec(dllexport) +#else +#define _ASYNCRTIMP __declspec(dllimport) +#endif +#endif + +#ifdef CASABLANCA_DEPRECATION_NO_WARNINGS +#define CASABLANCA_DEPRECATED(x) +#else +#define CASABLANCA_DEPRECATED(x) __declspec(deprecated(x)) +#endif diff --git a/Source/Shared/HookedUri/details/nosal.h b/Source/Shared/HookedUri/details/nosal.h new file mode 100644 index 00000000..4d7e583a --- /dev/null +++ b/Source/Shared/HookedUri/details/nosal.h @@ -0,0 +1,89 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +***/ + +#pragma once +// selected MS SAL annotations + +#ifdef _In_ +#undef _In_ +#endif +#define _In_ + +#ifdef _Inout_ +#undef _Inout_ +#endif +#define _Inout_ + +#ifdef _Out_ +#undef _Out_ +#endif +#define _Out_ + +#ifdef _In_z_ +#undef _In_z_ +#endif +#define _In_z_ + +#ifdef _Out_z_ +#undef _Out_z_ +#endif +#define _Out_z_ + +#ifdef _Inout_z_ +#undef _Inout_z_ +#endif +#define _Inout_z_ + +#ifdef _In_opt_ +#undef _In_opt_ +#endif +#define _In_opt_ + +#ifdef _Out_opt_ +#undef _Out_opt_ +#endif +#define _Out_opt_ + +#ifdef _Inout_opt_ +#undef _Inout_opt_ +#endif +#define _Inout_opt_ + +#ifdef _Out_writes_ +#undef _Out_writes_ +#endif +#define _Out_writes_(x) + +#ifdef _Out_writes_opt_ +#undef _Out_writes_opt_ +#endif +#define _Out_writes_opt_(x) + +#ifdef _In_reads_ +#undef _In_reads_ +#endif +#define _In_reads_(x) + +#ifdef _Inout_updates_bytes_ +#undef _Inout_updates_bytes_ +#endif +#define _Inout_updates_bytes_(x) \ No newline at end of file diff --git a/Source/Shared/HookedUri/details/uri.hpp b/Source/Shared/HookedUri/details/uri.hpp new file mode 100644 index 00000000..b57dd002 --- /dev/null +++ b/Source/Shared/HookedUri/details/uri.hpp @@ -0,0 +1,458 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Protocol independent support for URIs. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +using namespace xbox::services::cppresturi::utility::conversions; + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 26444 ) // ignore various unnamed objects +#pragma warning( disable : 26812 ) // enum instead of enum class +#endif + +namespace xbox { namespace services { namespace cppresturi { + +namespace web { namespace details +{ +xsapi_internal_string uri_components::join() +{ + // canonicalize components first + + // convert scheme to lowercase + std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), [](char c) { + return (char)tolower(c); + }); + + // convert host to lowercase + std::transform(m_host.begin(), m_host.end(), m_host.begin(), [](char c) { + return (char)tolower(c); + }); + + // canonicalize the path to have a leading slash if it's a full uri + if (!m_host.empty() && m_path.empty()) + { + m_path = "/"; + } + else if (!m_host.empty() && m_path[0] != '/') + { + m_path.insert(m_path.begin(), 1, '/'); + } + + xsapi_internal_string ret; + +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) + if (!m_scheme.empty()) + { + ret.append(m_scheme).append({ ':' }); + } + + if (!m_host.empty()) + { + ret.append("//"); + + if (!m_user_info.empty()) + { + ret.append(m_user_info).append({ '@' }); + } + + ret.append(m_host); + + if (m_port > 0) + { + char buf[16] = { 0 }; + sprintf_s(buf, sizeof(buf), ":%d", m_port); + ret.append(buf); + } + } + + if (!m_path.empty()) + { + // only add the leading slash when the host is present + if (!m_host.empty() && m_path.front() != '/') + { + ret.append({ '/' }); + } + + ret.append(m_path); + } + + if (!m_query.empty()) + { + ret.append({ '?' }).append(m_query); + } + + if (!m_fragment.empty()) + { + ret.append({ '#' }).append(m_fragment); + } + + return ret; +#else + xsapi_internal_ostringstream_t os; + os.imbue(std::locale::classic()); + + if (!m_scheme.empty()) + { + os << m_scheme << ':'; + } + + if (!m_host.empty()) + { + os << "//"; + + if (!m_user_info.empty()) + { + os << m_user_info << '@'; + } + + os << m_host; + + if (m_port > 0) + { + os << ':' << m_port; + } + } + + if (!m_path.empty()) + { + // only add the leading slash when the host is present + if (!m_host.empty() && m_path.front() != '/') + { + os << '/'; + } + os << m_path; + } + + if (!m_query.empty()) + { + os << '?' << m_query; + } + + if (!m_fragment.empty()) + { + os << '#' << m_fragment; + } + + return os.str(); +#endif +} +} + +using namespace xbox::services::cppresturi::web::details; + +uri::uri(const details::uri_components &components) : m_components(components) +{ + m_uri = m_components.join(); + if (!details::uri_parser::validate(m_uri)) + { + throw uri_exception(""); // provided uri is invalid : " + utility::conversions::to_utf8string(m_uri)); + } +} + +uri::uri(const xsapi_internal_string &uri_string) +{ + if (!details::uri_parser::parse(uri_string, m_components)) + { + throw uri_exception(""); // provided uri is invalid : " + utility::conversions::to_utf8string(uri_string)); + } + m_uri = m_components.join(); +} + +uri::uri(const char *uri_string): m_uri(uri_string) +{ + if (!details::uri_parser::parse(uri_string, m_components)) + { +#if 0 // this returns a non-mem hooked string which can't be changed so commenting it out since its not really needed + throw uri_exception("provided uri is invalid: " + utility::conversions::to_utf8string_internal(uri_string)); +#else + throw uri_exception(std::string()); +#endif + } + m_uri = m_components.join(); +} + +xsapi_internal_string uri::encode_impl(const xsapi_internal_string &utf8raw, const std::function& should_encode) +{ + const char * const hex = "0123456789ABCDEF"; + xsapi_internal_string encoded; + for (auto iter = utf8raw.begin(); iter != utf8raw.end(); ++iter) + { + // for utf8 encoded string, char ASCII can be greater than 127. + int ch = static_cast(*iter); + // ch should be same under both utf8 and utf16. + if(should_encode(ch)) + { + encoded.push_back('%'); + encoded.push_back(hex[(ch >> 4) & 0xF]); + encoded.push_back(hex[ch & 0xF]); + } + else + { + // ASCII don't need to be encoded, which should be same on both utf8 and utf16. + encoded.push_back((char)ch); + } + } + return encoded; +} + +/// +/// Encodes a string by converting all characters except for RFC 3986 unreserved characters to their +/// hexadecimal representation. +/// +xsapi_internal_string uri::encode_data_string(const xsapi_internal_string &raw) +{ + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_unreserved(ch); + }); +} + +xsapi_internal_string uri::encode_uri(const xsapi_internal_string &raw, uri::components::component component) +{ + // Note: we also encode the '+' character because some non-standard implementations + // encode the space character as a '+' instead of %20. To better interoperate we encode + // '+' to avoid any confusion and be mistaken as a space. + switch(component) + { + case components::user_info: + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_user_info_character(ch) + || ch == '%' || ch == '+'; + }); + case components::host: + return uri::encode_impl(raw, [](int ch) -> bool + { + // No encoding of ASCII characters in host name (RFC 3986 3.2.2) + return ch > 127; + }); + case components::path: + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_path_character(ch) + || ch == '%' || ch == '+'; + }); + case components::query: + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_query_character(ch) + || ch == '%' || ch == '+'; + }); + case components::fragment: + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_fragment_character(ch) + || ch == '%' || ch == '+'; + }); + case components::full_uri: + default: + return uri::encode_impl(raw, [](int ch) -> bool + { + return !uri_parser::is_unreserved(ch) && !uri_parser::is_reserved(ch); + }); + }; +} + +/// +/// Helper function to convert a hex character digit to a decimal character value. +/// Throws an exception if not a valid hex digit. +/// +static int hex_char_digit_to_decimal_char(int hex) +{ + int decimal; + if(hex >= '0' && hex <= '9') + { + decimal = hex - '0'; + } + else if(hex >= 'A' && hex <= 'F') + { + decimal = 10 + (hex - 'A'); + } + else if(hex >= 'a' && hex <= 'f') + { + decimal = 10 + (hex - 'a'); + } + else + { + throw uri_exception("Invalid hexadecimal digit"); + } + return decimal; +} + +xsapi_internal_string uri::decode(const xsapi_internal_string &encoded) +{ + xsapi_internal_string utf8raw; + for(auto iter = encoded.begin(); iter != encoded.end(); ++iter) + { + if(*iter == '%') + { + if(++iter == encoded.end()) + { + throw uri_exception("Invalid URI string, two hexadecimal digits must follow '%'"); + } + int decimal_value = hex_char_digit_to_decimal_char(static_cast(*iter)) << 4; + if(++iter == encoded.end()) + { + throw uri_exception("Invalid URI string, two hexadecimal digits must follow '%'"); + } + decimal_value += hex_char_digit_to_decimal_char(static_cast(*iter)); + + utf8raw.push_back(static_cast(decimal_value)); + } + else + { + // encoded string has to be ASCII. + utf8raw.push_back(reinterpret_cast(*iter)); + } + } + return utf8raw; +} + +std::vector uri::split_path(const xsapi_internal_string &path) +{ + std::vector results; + xsapi_internal_istringstream iss(path); + iss.imbue(std::locale::classic()); + xsapi_internal_string s; + + while (std::getline(iss, s, '/')) + { + if (!s.empty()) + { + results.push_back(s); + } + } + + return results; +} + +std::map uri::split_query(const xsapi_internal_string &query) +{ + std::map results; + + // Split into key value pairs separated by '&'. + size_t prev_amp_index = 0; + while(prev_amp_index != xsapi_internal_string::npos) + { + size_t amp_index = query.find_first_of('&', prev_amp_index); + if (amp_index == xsapi_internal_string::npos) + amp_index = query.find_first_of(';', prev_amp_index); + + xsapi_internal_string key_value_pair = query.substr( + prev_amp_index, + amp_index == xsapi_internal_string::npos ? query.size() - prev_amp_index : amp_index - prev_amp_index); + prev_amp_index = amp_index == xsapi_internal_string::npos ? xsapi_internal_string::npos : amp_index + 1; + + size_t equals_index = key_value_pair.find_first_of('='); + if(equals_index == xsapi_internal_string::npos) + { + continue; + } + else if (equals_index == 0) + { + xsapi_internal_string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + results[""] = value; + } + else + { + xsapi_internal_string key(key_value_pair.begin(), key_value_pair.begin() + equals_index); + xsapi_internal_string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + results[key] = value; + } + } + + return results; +} + +bool uri::validate(const xsapi_internal_string &uri_string) +{ + return uri_parser::validate(uri_string); +} + +uri uri::authority() const +{ + return uri_builder().set_scheme(this->scheme()).set_host(this->host()).set_port(this->port()).set_user_info(this->user_info()).to_uri(); +} + +uri uri::resource() const +{ + return uri_builder().set_path(this->path()).set_query(this->query()).set_fragment(this->fragment()).to_uri(); +} + +bool uri::operator == (const uri &other) const +{ + // Each individual URI component must be decoded before performing comparison. + // TFS # 375865 + + if (this->is_empty() && other.is_empty()) + { + return true; + } + else if (this->is_empty() || other.is_empty()) + { + return false; + } + else if (this->scheme() != other.scheme()) + { + // scheme is canonicalized to lowercase + return false; + } + else if(uri::decode(this->user_info()) != uri::decode(other.user_info())) + { + return false; + } + else if (uri::decode(this->host()) != uri::decode(other.host())) + { + // host is canonicalized to lowercase + return false; + } + else if (this->port() != other.port()) + { + return false; + } + else if (uri::decode(this->path()) != uri::decode(other.path())) + { + return false; + } + else if (uri::decode(this->query()) != uri::decode(other.query())) + { + return false; + } + else if (uri::decode(this->fragment()) != uri::decode(other.fragment())) + { + return false; + } + + return true; +} + +} + +} } } + +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif diff --git a/Source/Shared/HookedUri/details/uri_builder.hpp b/Source/Shared/HookedUri/details/uri_builder.hpp new file mode 100644 index 00000000..9a36e595 --- /dev/null +++ b/Source/Shared/HookedUri/details/uri_builder.hpp @@ -0,0 +1,134 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Builder for constructing URIs. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +namespace xbox { namespace services { namespace cppresturi { + +namespace web +{ + +namespace http +{ + // URI class has been moved from web::http namespace to web namespace. + // The below using declarations ensure we don't break existing code. + // Please use the web::uri class going forward. + using web::uri; + using web::uri_builder; +} + +uri_builder &uri_builder::append_path(const xsapi_internal_string &path, bool is_encode) +{ + if(path.empty() || path == "/") + { + return *this; + } + + auto encoded_path = is_encode ? uri::encode_uri(path, uri::components::path) : path; + auto thisPath = this->path(); + if(thisPath.empty() || thisPath == "/") + { + if(encoded_path.front() != '/') + { + set_path("/" + encoded_path); + } + else + { + set_path(encoded_path); + } + } + else if(thisPath.back() == '/' && encoded_path.front() == '/') + { + thisPath.pop_back(); + set_path(thisPath + encoded_path); + } + else if(thisPath.back() != '/' && encoded_path.front() != '/') + { + set_path(thisPath + "/" + encoded_path); + } + else + { + // Only one slash. + set_path(thisPath + encoded_path); + } + return *this; +} + +uri_builder &uri_builder::append_query(const xsapi_internal_string &query, bool is_encode) +{ + if(query.empty()) + { + return *this; + } + + auto encoded_query = is_encode ? uri::encode_uri(query, uri::components::query) : query; + auto thisQuery = this->query(); + if (thisQuery.empty()) + { + this->set_query(encoded_query); + } + else if(thisQuery.back() == '&' && encoded_query.front() == '&') + { + thisQuery.pop_back(); + this->set_query(thisQuery + encoded_query); + } + else if(thisQuery.back() != '&' && encoded_query.front() != '&') + { + this->set_query(thisQuery + "&" + encoded_query); + } + else + { + // Only one ampersand. + this->set_query(thisQuery + encoded_query); + } + return *this; +} + +uri_builder &uri_builder::append(const http::uri &relative_uri) +{ + append_path(relative_uri.path()); + append_query(relative_uri.query()); + this->set_fragment(this->fragment() + relative_uri.fragment()); + return *this; +} + +xsapi_internal_string uri_builder::to_string() +{ + return to_uri().to_string(); +} + +uri uri_builder::to_uri() +{ + return uri(m_uri); +} + +bool uri_builder::is_valid() +{ + return uri::validate(m_uri.join()); +} + +} // namespace web + +} } } diff --git a/Source/Shared/HookedUri/details/uri_parser.h b/Source/Shared/HookedUri/details/uri_parser.h new file mode 100644 index 00000000..88618e83 --- /dev/null +++ b/Source/Shared/HookedUri/details/uri_parser.h @@ -0,0 +1,219 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* URI parsing implementation +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include + +namespace xbox { namespace services { namespace cppresturi { + +namespace web { namespace details +{ + namespace uri_parser + { + + /// + /// Parses the uri, attempting to determine its validity. + /// + /// This function accepts both uris ('http://msn.com') and uri relative-references ('path1/path2?query') + /// + bool validate(const xsapi_internal_string &encoded_string); + + /// + /// Parses the uri, setting each provided string to the value of that component. Components + /// that are not part of the provided text are set to the empty string. Component strings + /// DO NOT contain their beginning or ending delimiters. + /// + /// This function accepts both uris ('http://msn.com') and uri relative-references ('path1/path2?query') + /// + bool parse(const xsapi_internal_string &encoded_string, uri_components &components); + + /// + /// Unreserved characters are those that are allowed in a URI but do not have a reserved purpose. They include: + /// - A-Z + /// - a-z + /// - 0-9 + /// - '-' (hyphen) + /// - '.' (period) + /// - '_' (underscore) + /// - '~' (tilde) + /// + inline bool is_unreserved(int c) + { + return xbox::services::cppresturi::utility::details::is_alnum((char)c) || c == '-' || c == '.' || c == '_' || c == '~'; + } + + /// + /// General delimiters serve as the delimiters between different uri components. + /// General delimiters include: + /// - All of these :/?#[]@ + /// + inline bool is_gen_delim(int c) + { + return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@'; + } + + /// + /// Subdelimiters are those characters that may have a defined meaning within component + /// of a uri for a particular scheme. They do not serve as delimiters in any case between + /// uri segments. sub_delimiters include: + /// - All of these !$&'()*+,;= + /// + inline bool is_sub_delim(int c) + { + switch (c) + { + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return true; + default: + return false; + } + } + + /// + /// Reserved characters includes the general delimiters and sub delimiters. Some characters + /// are neither reserved nor unreserved, and must be percent-encoded. + /// + inline bool is_reserved(int c) + { + return is_gen_delim(c) || is_sub_delim(c); + } + + /// + /// Legal characters in the scheme portion include: + /// - Any alphanumeric character + /// - '+' (plus) + /// - '-' (hyphen) + /// - '.' (period) + /// + /// Note that the scheme must BEGIN with an alpha character. + /// + inline bool is_scheme_character(int c) + { + return xbox::services::cppresturi::utility::details::is_alnum((char)c) || c == '+' || c == '-' || c == '.'; + } + + /// + /// Legal characters in the user information portion include: + /// - Any unreserved character + /// - The percent character ('%'), and thus any percent-endcoded octet + /// - The sub-delimiters + /// - ':' (colon) + /// + inline bool is_user_info_character(int c) + { + return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == ':'; + } + + /// + /// Legal characters in the host portion include: + /// - Any unreserved character + /// - The percent character ('%'), and thus any percent-endcoded octet + /// - The sub-delimiters + /// - ':' (colon) + /// - '[' (open bracket) + /// - ']' (close bracket) + /// + inline bool is_host_character(int c) + { + return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == ':' || c == '[' || c == ']'; + } + + /// + /// Legal characters in the authority portion include: + /// - Any unreserved character + /// - The percent character ('%'), and thus any percent-endcoded octet + /// - The sub-delimiters + /// - ':' (colon) + /// + /// Note that we don't currently support: + /// - IPv6 addresses (requires '[]') + /// + inline bool is_authority_character(int c) + { + return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == '@' || c == ':'; + } + + /// + /// Legal characters in the path portion include: + /// - Any unreserved character + /// - The percent character ('%'), and thus any percent-endcoded octet + /// - The sub-delimiters + /// - ':' (colon) + /// - '@' (ampersand) + /// + inline bool is_path_character(int c) + { + return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == '/' || c == ':' || c == '@'; + } + + /// + /// Legal characters in the query portion include: + /// - Any path character + /// - '?' (question mark) + /// + inline bool is_query_character(int c) + { + return is_path_character(c) || c == '?'; + } + + /// + /// Legal characters in the fragment portion include: + /// - Any path character + /// - '?' (question mark) + /// + inline bool is_fragment_character(int c) + { + // this is intentional, they have the same set of legal characters + return is_query_character(c); + } + + /// + /// Parses the uri, setting the given pointers to locations inside the given buffer. + /// 'encoded' is expected to point to an encoded zero-terminated string containing a uri + /// + bool inner_parse( + const char *encoded, + const char **scheme_begin, const char **scheme_end, + const char **uinfo_begin, const char **uinfo_end, + const char **host_begin, const char **host_end, + _Out_ int *port, + const char **path_begin, const char **path_end, + const char **query_begin, const char **query_end, + const char **fragment_begin, const char **fragment_end); + } +}} + +} } } \ No newline at end of file diff --git a/Source/Shared/HookedUri/details/uri_parser.hpp b/Source/Shared/HookedUri/details/uri_parser.hpp new file mode 100644 index 00000000..d22f99ca --- /dev/null +++ b/Source/Shared/HookedUri/details/uri_parser.hpp @@ -0,0 +1,369 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* URI parsing implementation +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include + +namespace xbox { namespace services { namespace cppresturi { + +namespace web { namespace details { namespace uri_parser +{ + +bool validate(const xsapi_internal_string& encoded_string) +{ + const char* scheme_begin = nullptr; + const char* scheme_end = nullptr; + const char* uinfo_begin = nullptr; + const char* uinfo_end = nullptr; + const char* host_begin = nullptr; + const char* host_end = nullptr; + int port_ptr = 0; + const char* path_begin = nullptr; + const char* path_end = nullptr; + const char* query_begin = nullptr; + const char* query_end = nullptr; + const char* fragment_begin = nullptr; + const char* fragment_end = nullptr; + + // perform a parse, but don't copy out the data + return inner_parse( + encoded_string.c_str(), + &scheme_begin, + &scheme_end, + &uinfo_begin, + &uinfo_end, + &host_begin, + &host_end, + &port_ptr, + &path_begin, + &path_end, + &query_begin, + &query_end, + &fragment_begin, + &fragment_end); +} + +bool parse(const xsapi_internal_string &encoded_string, uri_components &components) +{ + const char* scheme_begin = nullptr; + const char* scheme_end = nullptr; + const char* host_begin = nullptr; + const char* host_end = nullptr; + const char* uinfo_begin = nullptr; + const char* uinfo_end = nullptr; + int port_ptr = 0; + const char* path_begin = nullptr; + const char* path_end = nullptr; + const char* query_begin = nullptr; + const char* query_end = nullptr; + const char* fragment_begin = nullptr; + const char* fragment_end = nullptr; + + if (inner_parse( + encoded_string.c_str(), + &scheme_begin, + &scheme_end, + &uinfo_begin, + &uinfo_end, + &host_begin, + &host_end, + &port_ptr, + &path_begin, + &path_end, + &query_begin, + &query_end, + &fragment_begin, + &fragment_end)) + { + if (scheme_begin) + { + components.m_scheme.assign(scheme_begin, scheme_end); + + // convert scheme to lowercase + std::transform(components.m_scheme.begin(), components.m_scheme.end(), components.m_scheme.begin(), [](char c) { + return (char)tolower(c); + }); + } + else + { + components.m_scheme.clear(); + } + + if (uinfo_begin) + { + components.m_user_info.assign(uinfo_begin, uinfo_end); + } + + if (host_begin) + { + components.m_host.assign(host_begin, host_end); + + // convert host to lowercase + std::transform(components.m_host.begin(), components.m_host.end(), components.m_host.begin(), [](char c) { + return (char)tolower(c); + }); + } + else + { + components.m_host.clear(); + } + + if (port_ptr) + { + components.m_port = port_ptr; + } + else + { + components.m_port = 0; + } + + if (path_begin) + { + components.m_path.assign(path_begin, path_end); + } + else + { + // default path to begin with a slash for easy comparison + components.m_path = "/"; + } + + if (query_begin) + { + components.m_query.assign(query_begin, query_end); + } + else + { + components.m_query.clear(); + } + + if (fragment_begin) + { + components.m_fragment.assign(fragment_begin, fragment_end); + } + else + { + components.m_fragment.clear(); + } + + return true; + } + else + { + return false; + } +} + +bool inner_parse( + const char* encoded, + const char** scheme_begin, const char** scheme_end, + const char** uinfo_begin, const char** uinfo_end, + const char** host_begin, const char** host_end, + _Out_ int * port, + const char** path_begin, const char** path_end, + const char** query_begin, const char** query_end, + const char** fragment_begin, const char** fragment_end) +{ + *scheme_begin = nullptr; + *scheme_end = nullptr; + *uinfo_begin = nullptr; + *uinfo_end = nullptr; + *host_begin = nullptr; + *host_end = nullptr; + *port = 0; + *path_begin = nullptr; + *path_end = nullptr; + *query_begin = nullptr; + *query_end = nullptr; + *fragment_begin = nullptr; + *fragment_end = nullptr; + + const char*p = encoded; + + // IMPORTANT -- A uri may either be an absolute uri, or an relative-reference + // Absolute: 'http://host.com' + // Relative-Reference: '//:host.com', '/path1/path2?query', './path1:path2' + // A Relative-Reference can be disambiguated by parsing for a ':' before the first slash + + bool is_relative_reference = true; + const char*p2 = p; + for (;*p2 != '/' && *p2 != '\0'; p2++) + { + if (*p2 == ':') + { + // found a colon, the first portion is a scheme + is_relative_reference = false; + break; + } + } + + if (!is_relative_reference) + { + // the first character of a scheme must be a letter + if (!isalpha(*p)) + { + return false; + } + + // start parsing the scheme, it's always delimited by a colon (must be present) + *scheme_begin = p++; + for (;*p != ':'; p++) + { + if (!is_scheme_character(*p)) + { + return false; + } + } + *scheme_end = p; + + // skip over the colon + p++; + } + + // if we see two slashes next, then we're going to parse the authority portion + // later on we'll break up the authority into the port and host + const char*authority_begin = nullptr; + const char*authority_end = nullptr; + if (*p == '/' && p[1] == '/') + { + // skip over the slashes + p += 2; + authority_begin = p; + + // the authority is delimited by a slash (resource), question-mark (query) or octothorpe (fragment) + // or by EOS. The authority could be empty ('file:///C:\file_name.txt') + for (;*p != '/' && *p != '?' && *p != '#' && *p != '\0'; p++) + { + // We're NOT currently supporting IPv6, IPvFuture or username/password in authority + if (!is_authority_character(*p)) + { + return false; + } + } + authority_end = p; + + // now lets see if we have a port specified -- by working back from the end + if (authority_begin != authority_end) + { + // the port is made up of all digits + const char*port_begin = authority_end - 1; + for (;isdigit(*port_begin) && port_begin != authority_begin; port_begin--) + { } + + if (*port_begin == ':') + { + // has a port + *host_begin = authority_begin; + *host_end = port_begin; + + //skip the colon + port_begin++; + + *port = utility::conversions::scan_string(utility::string_t(port_begin, authority_end), std::locale::classic()); + } + else + { + // no port + *host_begin = authority_begin; + *host_end = authority_end; + } + + // look for a user_info component + const char*u_end = *host_begin; + for (;is_user_info_character(*u_end) && u_end != *host_end; u_end++) + { } + + if (*u_end == '@') + { + *host_begin = u_end+1; + *uinfo_begin = authority_begin; + *uinfo_end = u_end; + } + else + { + uinfo_end = uinfo_begin = nullptr; + } + } + } + + // if we see a path character or a slash, then the + // if we see a slash, or any other legal path character, parse the path next + if (*p == '/' || is_path_character(*p)) + { + *path_begin = p; + + // the path is delimited by a question-mark (query) or octothorpe (fragment) or by EOS + for (;*p != '?' && *p != '#' && *p != '\0'; p++) + { + if (!is_path_character(*p)) + { + return false; + } + } + *path_end = p; + } + + // if we see a ?, then the query is next + if (*p == '?') + { + // skip over the question mark + p++; + *query_begin = p; + + // the query is delimited by a '#' (fragment) or EOS + for (;*p != '#' && *p != '\0'; p++) + { + if (!is_query_character(*p)) + { + return false; + } + } + *query_end = p; + } + + // if we see a #, then the fragment is next + if (*p == '#') + { + // skip over the hash mark + p++; + *fragment_begin = p; + + // the fragment is delimited by EOS + for (;*p != '\0'; p++) + { + if (!is_fragment_character(*p)) + { + return false; + } + } + *fragment_end = p; + } + + return true; +} + +}}} + +} } } \ No newline at end of file diff --git a/Source/Shared/HookedUri/uri.h b/Source/Shared/HookedUri/uri.h new file mode 100644 index 00000000..1639a5ab --- /dev/null +++ b/Source/Shared/HookedUri/uri.h @@ -0,0 +1,35 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Protocol independent support for URIs. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ +#pragma once + +#ifndef _CASA_URI_H +#define _CASA_URI_H + +#include "HookedUri/base_uri.h" +#include "HookedUri/uri_builder.h" + +#endif + + diff --git a/Source/Shared/HookedUri/uri_builder.h b/Source/Shared/HookedUri/uri_builder.h new file mode 100644 index 00000000..0942f670 --- /dev/null +++ b/Source/Shared/HookedUri/uri_builder.h @@ -0,0 +1,297 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* 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. +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* Builder style class for creating URIs. +* +* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#include +#include +#include + +#include "HookedUri/base_uri.h" +#include "HookedUri/details/uri_parser.h" + +namespace xbox { namespace services { namespace cppresturi { + +namespace web +{ + /// + /// Builder for constructing URIs incrementally. + /// + class uri_builder + { + public: + + /// + /// Creates a builder with an initially empty URI. + /// + uri_builder() {} + + /// + /// Creates a builder with a existing URI object. + /// + /// Encoded string containing the URI. + uri_builder(const uri &uri_str): m_uri(uri_str.m_components) {} + + /// + /// Get the scheme component of the URI as an encoded string. + /// + /// The URI scheme as a string. + const xsapi_internal_string &scheme() const { return m_uri.m_scheme; } + + /// + /// Get the user information component of the URI as an encoded string. + /// + /// The URI user information as a string. + const xsapi_internal_string &user_info() const { return m_uri.m_user_info; } + + /// + /// Get the host component of the URI as an encoded string. + /// + /// The URI host as a string. + const xsapi_internal_string &host() const { return m_uri.m_host; } + + /// + /// Get the port component of the URI. Returns -1 if no port is specified. + /// + /// The URI port as an integer. + int port() const { return m_uri.m_port; } + + /// + /// Get the path component of the URI as an encoded string. + /// + /// The URI path as a string. + const xsapi_internal_string &path() const { return m_uri.m_path; } + + /// + /// Get the query component of the URI as an encoded string. + /// + /// The URI query as a string. + const xsapi_internal_string &query() const { return m_uri.m_query; } + + /// + /// Get the fragment component of the URI as an encoded string. + /// + /// The URI fragment as a string. + const xsapi_internal_string &fragment() const { return m_uri.m_fragment; } + + /// + /// Set the scheme of the URI. + /// + /// Uri scheme. + /// A reference to this uri_builder to support chaining. + uri_builder & set_scheme(const xsapi_internal_string &scheme) + { + m_uri.m_scheme = scheme; + return *this; + } + + /// + /// Set the user info component of the URI. + /// + /// User info as a decoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + uri_builder & set_user_info(const xsapi_internal_string &user_info, bool do_encoding = false) + { + m_uri.m_user_info = do_encoding ? uri::encode_uri(user_info, uri::components::user_info) : user_info; + return *this; + } + + /// + /// Set the host component of the URI. + /// + /// Host as a decoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + uri_builder & set_host(const xsapi_internal_string &host, bool do_encoding = false) + { + m_uri.m_host = do_encoding ? uri::encode_uri(host, uri::components::host) : host; + return *this; + } + + /// + /// Set the port component of the URI. + /// + /// Port as an integer. + /// A reference to this uri_builder to support chaining. + uri_builder & set_port(int port) + { + m_uri.m_port = port; + return *this; + } + + /// + /// Set the port component of the URI. + /// + /// Port as a string. + /// A reference to this uri_builder to support chaining. + /// When string can't be converted to an integer the port is left unchanged. + uri_builder & set_port(const xsapi_internal_string &port) + { + xsapi_internal_istringstream portStream(port); + int port_tmp; + portStream >> port_tmp; + if(portStream.fail() || portStream.bad()) + { + throw std::invalid_argument("invalid port argument, must be non empty string containing integer value"); + } + m_uri.m_port = port_tmp; + return *this; + } + + /// + /// Set the path component of the URI. + /// + /// Path as a decoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + uri_builder & set_path(const xsapi_internal_string &path, bool do_encoding = false) + { + m_uri.m_path = do_encoding ? uri::encode_uri(path, uri::components::path) : path; + return *this; + } + + + /// + /// Set the query component of the URI. + /// + /// Query as a decoded string. + /// Specify whether apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + uri_builder & set_query(const xsapi_internal_string &query, bool do_encoding = false) + { + m_uri.m_query = do_encoding ? uri::encode_uri(query, uri::components::query) : query; + return *this; + } + + /// + /// Set the fragment component of the URI. + /// + /// Fragment as a decoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + uri_builder & set_fragment(const xsapi_internal_string &fragment, bool do_encoding = false) + { + m_uri.m_fragment = do_encoding ? uri::encode_uri(fragment, uri::components::fragment) : fragment; + return *this; + } + + /// + /// Clears all components of the underlying URI in this uri_builder. + /// + void clear() + { + m_uri = details::uri_components(); + } + + /// + /// Appends another path to the path of this uri_builder. + /// + /// Path to append as a already encoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + _ASYNCRTIMP uri_builder &append_path(const xsapi_internal_string &path, bool do_encoding = false); + + /// + /// Appends another query to the query of this uri_builder. + /// + /// Query to append as a decoded string. + /// Specify whether to apply URI encoding to the given string. + /// A reference to this uri_builder to support chaining. + _ASYNCRTIMP uri_builder &append_query(const xsapi_internal_string &query, bool do_encoding = false); + + /// + /// Appends an relative uri (Path, Query and fragment) at the end of the current uri. + /// + /// The relative uri to append. + /// A reference to this uri_builder to support chaining. + _ASYNCRTIMP uri_builder &append(const uri &relative_uri); + + /// + /// Appends another query to the query of this uri_builder, encoding it first. This overload is useful when building a query segment of + /// the form "element=10", where the right hand side of the query is stored as a type other than a string, for instance, an integral type. + /// + /// The name portion of the query string + /// The value portion of the query string + /// A reference to this uri_builder to support chaining. + template + uri_builder &append_query(const xsapi_internal_string &name, const T &value, bool do_encoding = true) + { + auto encodedName = name; + auto encodedValue = ::utility::conversions::print_string(value, std::locale::classic()); + + if (do_encoding) + { + auto encodingCheck = [](int ch) + { + switch (ch) + { + // Encode '&', ';', and '=' since they are used + // as delimiters in query component. + case '&': + case ';': + case '=': + case '%': + case '+': + return true; + default: + return !::web::details::uri_parser::is_query_character(ch); + } + }; + encodedName = uri::encode_impl(encodedName, encodingCheck); + encodedValue = uri::encode_impl(encodedValue, encodingCheck); + } + + auto encodedQuery = encodedName; + encodedQuery.append(_XPLATSTR("=")); + encodedQuery.append(encodedValue); + // The query key value pair was already encoded by us or the user separately. + return append_query(encodedQuery, false); + } + + /// + /// Combine and validate the URI components into a encoded string. An exception will be thrown if the URI is invalid. + /// + /// The created URI as a string. + _ASYNCRTIMP xsapi_internal_string to_string(); + + /// + /// Combine and validate the URI components into a URI class instance. An exception will be thrown if the URI is invalid. + /// + /// The create URI as a URI class instance. + _ASYNCRTIMP uri to_uri(); + + /// + /// Validate the generated URI from all existing components of this uri_builder. + /// + /// Whether the URI is valid. + _ASYNCRTIMP bool is_valid(); + + private: + details::uri_components m_uri; + }; +} // namespace web + +} } } diff --git a/Source/Shared/Logger/log.cpp b/Source/Shared/Logger/log.cpp index 47656319..64ea892c 100644 --- a/Source/Shared/Logger/log.cpp +++ b/Source/Shared/Logger/log.cpp @@ -6,6 +6,16 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN +std::shared_ptr logger::get_logger() +{ + auto state = GlobalState::Get(); + if (state) + { + return state->Logger(); + } + return nullptr; +} + void logger::add_log_output(std::shared_ptr output) { m_log_outputs.emplace_back(output); diff --git a/Source/Shared/Logger/log.h b/Source/Shared/Logger/log.h index ee1a1db9..4f1e81c6 100644 --- a/Source/Shared/Logger/log.h +++ b/Source/Shared/Logger/log.h @@ -51,27 +51,27 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN class log_entry { public: - log_entry(HCTraceLevel level, std::string category); + log_entry(HCTraceLevel level, xsapi_internal_string category); - log_entry(HCTraceLevel level, std::string category, std::string msg); + log_entry(HCTraceLevel level, xsapi_internal_string category, xsapi_internal_string msg); - std::string level_to_string() const; + xsapi_internal_string level_to_string() const; - const std::stringstream& msg_stream() const { return m_message; } + const xsapi_internal_stringstream& msg_stream() const { return m_message; } - const std::string& category() const { return m_category; } + const xsapi_internal_string& category() const { return m_category; } HCTraceLevel get_log_level() const { return m_logLevel; } log_entry& operator<<(const char* data) { - m_message << xbox::services::convert::to_utf8string(data); + m_message << data; return *this; } - log_entry& operator<<(const std::string& data) + log_entry& operator<<(const xsapi_internal_string& data) { - m_message << xbox::services::convert::to_utf8string(data); + m_message << data; return *this; } @@ -82,7 +82,7 @@ public: return *this; } - log_entry& operator<<(const std::wstring& data) + log_entry& operator<<(const xsapi_internal_wstring& data) { m_message << xbox::services::convert::to_utf8string(data); return *this; @@ -98,8 +98,8 @@ public: private: HCTraceLevel m_logLevel; - std::string m_category; - std::stringstream m_message; + xsapi_internal_string m_category; + xsapi_internal_stringstream m_message; }; class log_output @@ -122,9 +122,9 @@ public: protected: // This function is to write the string to the final output, don't need to be thread safe. - virtual void write(_In_ HCTraceLevel level, _In_ const std::string& msg); + virtual void write(_In_ HCTraceLevel level, _In_ const xsapi_internal_string& msg); - virtual std::string format_log(_In_ const log_entry& entry); + virtual xsapi_internal_string format_log(_In_ const log_entry& entry); private: mutable std::mutex m_mutex; @@ -135,14 +135,7 @@ class logger public: logger() {} - static std::shared_ptr get_logger() - { - auto singleton = get_xsapi_singleton(); - if (singleton) - return singleton->m_logger; - else - return nullptr; - } + static std::shared_ptr get_logger(); void set_log_level(HCTraceLevel level); void add_log_output(std::shared_ptr output); @@ -152,7 +145,7 @@ public: void operator+=(const log_entry& record); private: - std::vector> m_log_outputs; + Vector> m_log_outputs; }; class logger_raii diff --git a/Source/Shared/Logger/log_entry.cpp b/Source/Shared/Logger/log_entry.cpp index 1bae3a6d..e3c90864 100644 --- a/Source/Shared/Logger/log_entry.cpp +++ b/Source/Shared/Logger/log_entry.cpp @@ -6,20 +6,20 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -log_entry::log_entry(HCTraceLevel level, std::string category) : +log_entry::log_entry(HCTraceLevel level, xsapi_internal_string category) : m_logLevel(level), m_category(std::move(category)) { } -log_entry::log_entry(HCTraceLevel level, std::string category, std::string msg) : +log_entry::log_entry(HCTraceLevel level, xsapi_internal_string category, xsapi_internal_string msg) : m_logLevel(level), m_category(std::move(category)) { m_message << msg; } -std::string log_entry::level_to_string() const +xsapi_internal_string log_entry::level_to_string() const { switch (m_logLevel) { diff --git a/Source/Shared/Logger/log_hc_output.cpp b/Source/Shared/Logger/log_hc_output.cpp index b388a6cd..9c444877 100644 --- a/Source/Shared/Logger/log_hc_output.cpp +++ b/Source/Shared/Logger/log_hc_output.cpp @@ -6,7 +6,7 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -void log_hc_output::write(_In_ HCTraceLevel level, _In_ const std::string& msg) +void log_hc_output::write(_In_ HCTraceLevel level, _In_ const xsapi_internal_string& msg) { HC_TRACE_MESSAGE(XSAPI, level, msg.c_str()); } diff --git a/Source/Shared/Logger/log_hc_output.h b/Source/Shared/Logger/log_hc_output.h index 7ab94ef7..e022c414 100644 --- a/Source/Shared/Logger/log_hc_output.h +++ b/Source/Shared/Logger/log_hc_output.h @@ -11,7 +11,7 @@ class log_hc_output : public log_output public: log_hc_output() : log_output() {} - void write(_In_ HCTraceLevel level, _In_ const std::string& msg) override; + void write(_In_ HCTraceLevel level, _In_ const xsapi_internal_string& msg) override; }; NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/Logger/log_output.cpp b/Source/Shared/Logger/log_output.cpp index 6132a3d8..7ca7f4cb 100644 --- a/Source/Shared/Logger/log_output.cpp +++ b/Source/Shared/Logger/log_output.cpp @@ -13,20 +13,20 @@ log_output::log_output() void log_output::add_log(_In_ const log_entry& entry) { - std::string msg = format_log(entry); + xsapi_internal_string msg = format_log(entry); { std::lock_guard lock(m_mutex); write(entry.get_log_level(), msg); } } -void log_output::write(_In_ HCTraceLevel level, _In_ const std::string& msg) +void log_output::write(_In_ HCTraceLevel level, _In_ const xsapi_internal_string& msg) { UNREFERENCED_PARAMETER(level); UNREFERENCED_PARAMETER(msg); } -std::string +xsapi_internal_string log_output::format_log(_In_ const log_entry& entry) { return entry.msg_stream().str(); diff --git a/Source/Shared/WinRT/local_config_winrt.cpp b/Source/Shared/WinRT/local_config_winrt.cpp index 078d8dfe..c7046cbd 100644 --- a/Source/Shared/WinRT/local_config_winrt.cpp +++ b/Source/Shared/WinRT/local_config_winrt.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "local_config.h" -#include "xbox_system_factory.h" #include "xsapi_utils.h" using namespace std; @@ -30,7 +29,7 @@ xbl_result local_config::read() #if HC_PLATFORM == HC_PLATFORM_UWP Windows::ApplicationModel::Package^ package = Windows::ApplicationModel::Package::Current; Windows::Storage::StorageFolder^ installedLocation = package->InstalledLocation; - string_t configPath = string_t(installedLocation->Path->Data()) + _T("\\xboxservices.config"); + xsapi_internal_string_t configPath = xsapi_internal_string_t(installedLocation->Path->Data()) + L"\\xboxservices.config"; #elif HC_PLATFORM == HC_PLATFORM_WIN32 // Don't rely on the current directory to be set correctly. // Instead assume xboxservices.config is next to the exe @@ -42,15 +41,15 @@ xbl_result local_config::read() *lastSlash = L'\0'; } - stringstream_t path; + xsapi_internal_stringstream_t path; path << processPath << _T("\\xboxservices.config"); - string_t configPath = path.str(); + xsapi_internal_string_t configPath = path.str(); #endif - string_t fileData = utils::read_file_to_string(configPath); + xsapi_internal_string_t fileData = utils::read_file_to_string(configPath); if( !fileData.empty() ) { - m_jsonConfig.Parse(utils::internal_string_from_string_t(fileData).c_str()); + m_jsonConfig.Parse(xbox::services::convert::to_utf8string(fileData).c_str()); if (!m_jsonConfig.HasParseError()) { return xbl_result(); diff --git a/Source/Shared/a/http_call_jni.cpp b/Source/Shared/a/http_call_jni.cpp index e1a8e49f..c0db21f4 100644 --- a/Source/Shared/a/http_call_jni.cpp +++ b/Source/Shared/a/http_call_jni.cpp @@ -1,12 +1,10 @@ #include "pch.h" #include "http_call_jni.h" #include -#include "xbox_system_factory.h" -#include "xsapi_utils.h" #include #include "jni_utils.h" -#include "Logger/log.h" #include "http_call_legacy.h" +#include "a\java_interop.h" #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "HttpCall", __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "HttpCall", __VA_ARGS__)) @@ -312,19 +310,50 @@ JNIEXPORT jlong JNICALL Java_com_microsoft_xbox_idp_util_HttpCall_create jstring_t strMethod(env, method); jstring_t strEndpoint(env, endpoint); jstring_t strPathAndQuery(env, pathAndQuery); - std::shared_ptr ctx(new xbox::services::XboxLiveContextSettings()); LOGD("Create HttpCall with uri %s", strEndpoint.get()); - std::shared_ptr* http_call = new std::shared_ptr( - xbox::services::system::xbox_system_factory::get_factory()->create_http_call( - ctx, - strMethod, - strEndpoint, - strPathAndQuery, - xbox::services::xbox_live_api::unspecified)); - (*http_call)->set_add_default_headers(addDefaultHeaders); - return reinterpret_cast(http_call); + std::shared_ptr* legacyHttpCallPtr{ nullptr }; + + auto user = java_interop::get_java_interop_singleton()->GetStoredUser(); + if (user) + { + auto userCopyResult = user->Copy(); + if (Succeeded(userCopyResult)) + { + String fullUrl{ strEndpoint.get() }; + xbox::services::uri path{ strPathAndQuery.get() }; + + if (!path.is_empty()) + { + fullUrl += path.to_string(); + } + + auto httpCall = MakeShared(userCopyResult.ExtractPayload()); + HRESULT hr = httpCall->Init( + std::shared_ptr{ new xbox::services::XboxLiveContextSettings }, + strMethod.get(), + fullUrl, + xbox::services::xbox_live_api::unspecified + ); + + if (SUCCEEDED(hr)) + { + // legacy http_call doesn't duplicate the provided XblHttpCall handle so do it before passing. + // This seems like a poor design, but keeping behavior same for now + httpCall->AddRef(); + + web::uri_builder uriBuilder; + uriBuilder.append(strPathAndQuery.get()); + auto legacyHttpCall = std::make_shared(httpCall.get(), strMethod.get(), strEndpoint.get(), uriBuilder.to_uri()); + legacyHttpCallPtr = new std::shared_ptr(std::move(legacyHttpCall)); + + (*legacyHttpCallPtr)->set_add_default_headers(addDefaultHeaders); + } + } + } + + return reinterpret_cast(legacyHttpCallPtr); } /* diff --git a/Source/Shared/a/interop_jni.cpp b/Source/Shared/a/interop_jni.cpp index 705cbb2f..2396d5a8 100644 --- a/Source/Shared/a/interop_jni.cpp +++ b/Source/Shared/a/interop_jni.cpp @@ -1,5 +1,7 @@ #include "pch.h" #include "a/java_interop.h" +#include +#include "uri_impl.h" #ifdef __cplusplus extern "C" { diff --git a/Source/Shared/a/telemetry_a.cpp b/Source/Shared/a/telemetry_a.cpp deleted file mode 100644 index 3a5b998d..00000000 --- a/Source/Shared/a/telemetry_a.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" -#include "telemetry.h" -#include "jni.h" -#include "jni_utils.h" -#include - -#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "XSAPI.Android", __VA_ARGS__)) -#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "XSAPI.Android", __VA_ARGS__)) - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -void xsapi_telemetry::write_event_jni(JNIEnv* env, jclass clsInterop, jstring json) -{ - jstring_t eventPayload(env, json); - - // Might want to eventually pass the xal user handle as a parameter, but for now just remember the last signed in - // in user we've seen - XalUserHandle user = xbox::services::get_xsapi_singleton()->m_lastSignedInUser.load(); - if (user != nullptr) - { - xbox::services::xsapi_telemetry::get_singleton()->write_event(user, "JNIEvent", eventPayload.get()); - } -} - -bool xsapi_telemetry::register_natives(JNIEnv *env, jobject clsLoader, jmethodID loadClass) -{ - JNINativeMethod telemetryMethods[] = - { - { - "WriteEvent", - "(Ljava/lang/String;)V", - (void*)&xbox::services::xsapi_telemetry::write_event_jni - } - }; - - jstring clsName = env->NewStringUTF("com/microsoft/xbox/telemetry/helpers/UTCTelemetry"); - JNI_ERROR_CHECK(env); - jclass cls = (jclass)env->CallObjectMethod(clsLoader, loadClass, clsName); - env->DeleteLocalRef(clsName); - if (cls == NULL) { - LOGE("Failed to load class com/microsoft/xbox/telemetry/helpers/UTCTelemetry"); - return false; - } - auto size = (sizeof(telemetryMethods) / sizeof (telemetryMethods[0])); - - if (env->RegisterNatives(cls, telemetryMethods, size) != 0) { - LOGE("Failed to register native telemetryMethods"); - env->DeleteLocalRef(cls); - return false; - } - env->DeleteLocalRef(cls); - LOGD("Successfully registerered telemetryMethods"); - return true; -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/async_helpers.cpp b/Source/Shared/async_helpers.cpp index 2ad1214f..95785319 100644 --- a/Source/Shared/async_helpers.cpp +++ b/Source/Shared/async_helpers.cpp @@ -169,7 +169,11 @@ std::shared_ptr PeriodicTask::MakeAndRun( std::function task ) noexcept { - auto periodicTask = std::shared_ptr(new (Alloc(sizeof(PeriodicTask))) PeriodicTask{ queue, interval, std::move(task) }); + auto periodicTask = std::shared_ptr( + new (Alloc(sizeof(PeriodicTask))) PeriodicTask{ queue, interval, std::move(task) }, + Deleter(), + Allocator() + ); periodicTask->m_queue.RunWork([weakThis = std::weak_ptr{ periodicTask }] { @@ -295,7 +299,10 @@ HRESULT RunAsync( } catch (...) { + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_UNNAMED_CUSTOM_OBJ; LOGS_ERROR << "Unexpected exception in " << __FUNCTION__ << ", completing XAsyncOperation."; + DISABLE_WARNING_POP; return E_UNEXPECTED; } // For DoWork, GetResult, and Cancel, we have nothing to do. Invoke provider and handle any exceptions. diff --git a/Source/Shared/build_version.h b/Source/Shared/build_version.h index 8bb92e4d..8b6483be 100644 --- a/Source/Shared/build_version.h +++ b/Source/Shared/build_version.h @@ -9,4 +9,4 @@ //********************************************************* #pragma once -#define XBOX_SERVICES_API_VERSION_STRING "2020.11.20210116.1" +#define XBOX_SERVICES_API_VERSION_STRING "2021.02.20210318.2" diff --git a/Source/Shared/enum_traits.h b/Source/Shared/enum_traits.h index 33a4bcec..a48055a6 100644 --- a/Source/Shared/enum_traits.h +++ b/Source/Shared/enum_traits.h @@ -16,10 +16,13 @@ template class StaticString { public: + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_UNINITIALIZED_MEMBER; constexpr StaticString(const char* name) noexcept : StaticString{ name, std::make_index_sequence{} } { } + DISABLE_WARNING_POP; constexpr operator const char*() const noexcept { diff --git a/Source/Shared/errors.cpp b/Source/Shared/errors.cpp index 1d7bf6e0..408b2d9b 100644 --- a/Source/Shared/errors.cpp +++ b/Source/Shared/errors.cpp @@ -24,6 +24,7 @@ namespace legacy std::string xbox_services_error_code_category_impl::message(_In_ int errorCode) const _NOEXCEPT { +#if 0 // this returns a non-mem hooked string which can't be changed so commenting it out since its not really needed xbl_error_code code = static_cast(errorCode); switch (code) { @@ -173,10 +174,15 @@ namespace legacy return msg.str(); } } +#else + UNREFERENCED_PARAMETER(errorCode); + return std::string(); +#endif } std::string xbox_services_error_condition_category_impl::message(_In_ int errorCode) const _NOEXCEPT { +#if 0 // this returns a non-mem hooked string which can't be changed so commenting it out since its not really needed xbl_error_condition code = static_cast(errorCode); switch (code) @@ -200,6 +206,10 @@ namespace legacy return msg.str(); } } +#else + UNREFERENCED_PARAMETER(errorCode); + return std::string(); +#endif } bool xbox_services_error_condition_category_impl::equivalent( diff --git a/Source/Shared/errors_legacy.h b/Source/Shared/errors_legacy.h index 920c75f3..bc40039a 100644 --- a/Source/Shared/errors_legacy.h +++ b/Source/Shared/errors_legacy.h @@ -1258,8 +1258,8 @@ class xbl_result public: xbl_result(); xbl_result(_In_ T payload); - xbl_result(_In_ std::error_code errorCode, _In_ std::string errorMessage = std::string()); - xbl_result(_In_ T payload, _In_ std::error_code errorCode, _In_ std::string errorMessage = std::string()); + xbl_result(_In_ std::error_code errorCode, _In_ xsapi_internal_string errorMessage = xsapi_internal_string()); + xbl_result(_In_ T payload, _In_ std::error_code errorCode, _In_ xsapi_internal_string errorMessage = xsapi_internal_string()); xbl_result(_In_ const xbl_result&); xbl_result& operator=(_In_ const xbl_result&); @@ -1303,18 +1303,18 @@ class xbl_result /// Returns call specific debug information. /// It is not localized, so only use for debugging purposes. /// - const std::string& err_message() const; + const xsapi_internal_string& err_message() const; /// /// Sets error code debug information. /// It is not localized, so only use for debugging purposes. /// - void _Set_err_message(std::string errMessage); + void _Set_err_message(xsapi_internal_string errMessage); private: T m_payload{}; std::error_code m_errorCode{}; - std::string m_errorMessage; + xsapi_internal_string m_errorMessage; }; template<> @@ -1408,7 +1408,7 @@ class xbl_result template xbl_result::xbl_result() : - m_errorMessage(std::string()) + m_errorMessage(xsapi_internal_string()) { m_errorCode = make_error_code(xbl_error_code::no_error); } @@ -1416,7 +1416,7 @@ xbl_result::xbl_result() : template xbl_result::xbl_result(_In_ T payload) : m_payload(std::move(payload)), - m_errorMessage(std::string()) + m_errorMessage(xsapi_internal_string()) { m_errorCode = make_error_code(xbl_error_code::no_error); } @@ -1424,7 +1424,7 @@ xbl_result::xbl_result(_In_ T payload) : template xbl_result::xbl_result( _In_ std::error_code errorCode, - _In_ std::string errorMessage + _In_ xsapi_internal_string errorMessage ) : m_errorCode(std::move(errorCode)), m_errorMessage(std::move(errorMessage)) @@ -1435,7 +1435,7 @@ template xbl_result::xbl_result( _In_ T payload, _In_ std::error_code errorCode, - _In_ std::string errorMessage + _In_ xsapi_internal_string errorMessage ) : m_payload(std::move(payload)), m_errorCode(std::move(errorCode)), @@ -1474,13 +1474,13 @@ void xbl_result::_Set_err(std::error_code errCode) } template -const std::string& xbl_result::err_message() const +const xsapi_internal_string& xbl_result::err_message() const { return m_errorMessage; } template -void xbl_result::_Set_err_message(std::string errorMsg) +void xbl_result::_Set_err_message(xsapi_internal_string errorMsg) { m_errorMessage = std::move(errorMsg); } diff --git a/Source/Shared/fault_injection.cpp b/Source/Shared/fault_injection.cpp new file mode 100644 index 00000000..6bbb4c71 --- /dev/null +++ b/Source/Shared/fault_injection.cpp @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +#include "pch.h" +#include "fault_injection.h" + +#if _DEBUG // fault injection only enabled on debug bits so as not to impact retail titles +static fault_injection g_faultInjection; // not hanging this off of global state since it needs to keep between XblCleanups so long test runs are useful +#endif + +STDAPI_(void) XblEnableFaultInjection(_In_ uint64_t featureId) XBL_NOEXCEPT +{ +#if _DEBUG // fault injection only enabled on debug bits so as not to impact retail titles + g_faultInjection.m_enabledFeatureMask |= featureId; +#else + UNREFERENCED_PARAMETER(featureId); +#endif +} + +STDAPI_(uint64_t) XblGetFaultCounter() +{ +#if _DEBUG // testing feature only enabled on debug bits so as not to impact retail titles + return g_faultInjection.m_failTotalCounter; +#else + return 0; +#endif +} + +STDAPI_(void) XblSetFaultInjectOptions(int64_t failFreq, uint64_t freqChangeSpeed, int64_t freqChangeAmount) +{ +#if _DEBUG // testing feature only enabled on debug bits so as not to impact retail titles + g_faultInjection.m_failFreq = failFreq; + g_faultInjection.m_freqChangeSpeed = freqChangeSpeed; + g_faultInjection.m_freqChangeAmount = freqChangeAmount; +#else + UNREFERENCED_PARAMETER(failFreq); + UNREFERENCED_PARAMETER(freqChangeSpeed); + UNREFERENCED_PARAMETER(freqChangeAmount); +#endif +} + +STDAPI_(bool) XblShouldFaultInject(_In_ uint64_t featureId) +{ +#if _DEBUG // testing feature only enabled on debug bits so as not to impact retail titles + if ((g_faultInjection.m_enabledFeatureMask & featureId) == featureId) + { + g_faultInjection.m_freqChangeCounter++; + g_faultInjection.m_freqChangeCounter %= g_faultInjection.m_freqChangeSpeed; + if (g_faultInjection.m_freqChangeCounter == 0) + { + // Alter the fail freq every so often so it doesn't just fall into testing a repeated calling pattern + g_faultInjection.m_failFreq += g_faultInjection.m_freqChangeAmount; + g_faultInjection.m_failFreq = std::max(0, g_faultInjection.m_failFreq); + } + + g_faultInjection.m_failTotalCounter++; + g_faultInjection.m_failCounter++; + g_faultInjection.m_failCounter %= g_faultInjection.m_failFreq; + return (g_faultInjection.m_failCounter == 0); + } +#else + UNREFERENCED_PARAMETER(featureId); +#endif + + return false; +} + diff --git a/Source/Shared/fault_injection.h b/Source/Shared/fault_injection.h new file mode 100644 index 00000000..81459c42 --- /dev/null +++ b/Source/Shared/fault_injection.h @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +#pragma once + +#define INJECTION_FEATURE_USER 0x0001 +#define INJECTION_FEATURE_HTTP 0x0002 + +extern "C" +{ +STDAPI_(void) XblEnableFaultInjection(_In_ uint64_t featureId) XBL_NOEXCEPT; +STDAPI_(bool) XblShouldFaultInject(_In_ uint64_t featureId); +STDAPI_(uint64_t) XblGetFaultCounter(); +STDAPI_(void) XblSetFaultInjectOptions(int64_t failFreq, uint64_t freqChangeSpeed, int64_t freqChangeAmount); +} + +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN + +struct fault_injection +{ + uint64_t m_enabledFeatureMask{ 0 }; + uint64_t m_failCounter{ 0 }; + uint64_t m_failTotalCounter{ 0 }; + int64_t m_failFreq{ 3 }; + + // Alter the fail freq every so often so it doesn't just fall into testing a repeated calling pattern + uint64_t m_freqChangeCounter{ 0 }; + uint64_t m_freqChangeSpeed{ 7 }; + int64_t m_freqChangeAmount{ 1 }; +}; + +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/global_state.cpp b/Source/Shared/global_state.cpp index a4d28df9..85887bab 100644 --- a/Source/Shared/global_state.cpp +++ b/Source/Shared/global_state.cpp @@ -7,24 +7,37 @@ #include "multiplayer_manager_internal.h" #include "social_manager_internal.h" #include "real_time_activity_manager.h" +#include "Logger/log_hc_output.h" +#if HC_PLATFORM == HC_PLATFORM_ANDROID +#include "a/utils_a.h" +#include "a/java_interop.h" +#endif + +HC_DEFINE_TRACE_AREA(XSAPI, HCTraceLevel::Verbose); NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -// Local Storage in Android is dependent on the JNI Initialization done in xsapi_singleton->Initialize +// Local Storage in Android is dependent on the JNI Initialization done in GlobalState::Create // Only on Android the initialization of m_localStorage is done outside of the constructor. GlobalState::GlobalState( _In_ const XblInitArgs* args ) : - singleton{ MakeShared() }, m_taskQueue{ args ? TaskQueue::DeriveWorkerQueue(args->queue) : nullptr }, - m_achievementsManager{ MakeShared() }, + m_achievementsManager{ MakeShared() }, m_multiplayerManager{ MakeShared() }, m_socialManager{ MakeShared() }, - m_rtaManager{ MakeShared(m_taskQueue) } + m_rtaManager{ MakeShared(m_taskQueue) }, #if HC_PLATFORM != HC_PLATFORM_ANDROID - , m_localStorage{ MakeShared(m_taskQueue) } + m_localStorage{ MakeShared(m_taskQueue) }, #endif + m_appConfig{ MakeShared() }, + m_logger{ MakeShared() } { + m_logger->add_log_output(MakeShared()); + +#if _DEBUG && XSAPI_UNIT_TESTS && XSAPI_PROFILE + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif } HRESULT GlobalState::Create( @@ -55,21 +68,74 @@ HRESULT GlobalState::Create( auto state = std::shared_ptr( new (Alloc(sizeof(GlobalState))) GlobalState(args), - Deleter() + Deleter(), + Allocator() ); - RETURN_HR_IF_FAILED(state->singleton->Initialize(args)); - - // Local Storage in Android is dependent on the JNI Initialization done in xsapi_singleton->Initialize - // Only on Android the initialization of m_localStorage is done outside of the constructor. #if HC_PLATFORM == HC_PLATFORM_ANDROID + // TODO Should make the java interop singleton a member of GlobalState rather than a separate static + auto javaInteropInitResult = xbox::services::java_interop::get_java_interop_singleton()->initialize( + args->javaVM, + args->applicationContext + ); + if (javaInteropInitResult.err()) + { + return utils::convert_xbox_live_error_code_to_hresult(javaInteropInitResult.err()); + } +#endif + +#if HC_PLATFORM == HC_PLATFORM_ANDROID + // Local Storage in Android is dependent on the JNI Initialization so create LocalStorage now. state->m_localStorage = MakeShared(state->m_taskQueue); #endif #if HC_PLATFORM == HC_PLATFORM_WIN32 + // On Win32, set Local Storage path using init args RETURN_HR_IF_FAILED(state->m_localStorage->SetStoragePath(args->localStoragePath)); #endif +#if HC_PLATFORM != HC_PLATFORM_XDK && HC_PLATFORM != HC_PLATFORM_UWP + RETURN_HR_INVALIDARGUMENT_IF_NULL(args->scid); + RETURN_HR_IF_FAILED(state->m_appConfig->Initialize(args->scid)); +#else + RETURN_HR_IF_FAILED(state->m_appConfig->Initialize()); +#endif + +#if HC_PLATFORM_IS_EXTERNAL + state->m_appConfig->SetAppId(args->appId); + state->m_appConfig->SetAppVer(args->appVer); + state->m_appConfig->SetOsName(args->osName); + state->m_appConfig->SetOsVersion(args->osVersion); + state->m_appConfig->SetOsLocale(args->osLocale); + state->m_appConfig->SetDeviceClass(args->deviceClass); + state->m_appConfig->SetDeviceId(args->deviceId); +#endif + +#if HC_PLATFORM == HC_PLATFORM_IOS + if (args->apnsEnvironment) + { + state->m_appConfig->SetAPNSEnvironment(args->apnsEnvironment); + } +#endif + +#if HC_PLATFORM == HC_PLATFORM_XDK + // Initialize achievements provider properties + RETURN_HR_IF_FAILED(CoCreateGuid(&state->m_achievementsSessionId)); + + CHAR strTitleId[16] = ""; + sprintf_s(strTitleId, "%0.8X", state->m_appConfig->TitleId()); + + Stringstream achievementsProviderName; + achievementsProviderName << "XSAPI_" << strTitleId; + state->m_achivementsEventProviderName = achievementsProviderName.str(); +#endif + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_GDK + // Generate locales + state->m_locales = utils::generate_locales(); +#endif + + // GlobalState object has been created and initialized successfully at this point so store it. (void)AccessHelper(AccessMode::SET, state); #if HC_PLATFORM == HC_PLATFORM_GDK @@ -287,7 +353,6 @@ size_t GlobalState::EraseUserChangeHandler(uint64_t token) noexcept return m_userChangeHandlers.erase(token); } - size_t GlobalState::EraseUserExpiredToken(uint64_t xuid) noexcept { std::lock_guard lock{ m_mutex }; @@ -324,6 +389,16 @@ std::shared_ptr GlobalState::LocalStorage() const noexcept return m_localStorage; } +std::shared_ptr GlobalState::AppConfig() const noexcept +{ + return m_appConfig; +} + +std::shared_ptr GlobalState::Logger() const noexcept +{ + return m_logger; +} + std::shared_ptr GlobalState::GetSharedThis() { return shared_from_this(); @@ -332,7 +407,8 @@ std::shared_ptr GlobalState::GetSharedThis() #if HC_PLATFORM == HC_PLATFORM_GDK XblFunctionContext GlobalState::AddAppChangeNotificationHandler( - _In_ AppChangeNotificationHandler appChangeNotificationHandler) + _In_ AppChangeNotificationHandler appChangeNotificationHandler +) noexcept { std::lock_guard lock{ m_mutex }; m_appChangeNotificationHandlers.emplace(m_nextAppChangeHandlerToken, appChangeNotificationHandler); @@ -370,6 +446,29 @@ void GlobalState::RemoveAppChangeNotificationHandler( std::lock_guard lock{ m_mutex }; m_appChangeNotificationHandlers.erase(token); } + #endif +#if HC_PLATFORM == HC_PLATFORM_XDK +const String& GlobalState::AchievementsProviderName() const noexcept +{ + return m_achivementsEventProviderName; +} + +const GUID& GlobalState::AchievementsSessionId() const noexcept +{ + return m_achievementsSessionId; +} +#endif + +const String& GlobalState::Locales() const noexcept +{ + return m_locales; +} + +void GlobalState::OverrideLocales(String&& locales) noexcept +{ + m_locales = std::move(locales); +} + NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/global_state.h b/Source/Shared/global_state.h index ac030329..88c386c4 100644 --- a/Source/Shared/global_state.h +++ b/Source/Shared/global_state.h @@ -5,6 +5,7 @@ #include "service_call_routed_handler.h" #include "local_storage.h" +#include "fault_injection.h" #if HC_PLATFORM == HC_PLATFORM_GDK #include @@ -15,37 +16,24 @@ // for UnitTests, but it can be enabled for debugging in other situations as well. #define TRACK_ASYNC XSAPI_UNIT_TESTS -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - // Forward declarations -namespace achievements -{ - namespace manager - { - class AchievementsManager; - } -} +NAMESPACE_MICROSOFT_XBOX_SERVICES_ACHIEVEMENTS_MANAGER_CPP_BEGIN + class AchievementsManager; +NAMESPACE_MICROSOFT_XBOX_SERVICES_ACHIEVEMENTS_MANAGER_CPP_END -namespace multiplayer -{ - namespace manager - { - class MultiplayerManager; - } -} +NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_BEGIN + class MultiplayerManager; +NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_END -namespace social -{ - namespace manager - { - class SocialManager; - } -} +NAMESPACE_MICROSOFT_XBOX_SERVICES_SOCIAL_MANAGER_CPP_BEGIN + class SocialManager; +NAMESPACE_MICROSOFT_XBOX_SERVICES_SOCIAL_MANAGER_CPP_END -namespace real_time_activity -{ +NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_BEGIN class RealTimeActivityManager; -} +NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_END + +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN #if HC_PLATFORM == HC_PLATFORM_GDK typedef Function AppChangeNotificationHandler; @@ -84,24 +72,33 @@ public: std::shared_ptr LocalStorage() const noexcept; + std::shared_ptr AppConfig() const noexcept; + + std::shared_ptr Logger() const noexcept; + #if HC_PLATFORM == HC_PLATFORM_GDK XblFunctionContext AddAppChangeNotificationHandler( - _In_ AppChangeNotificationHandler routine); - - static void AppStateChangeNotificationReceived( - BOOLEAN quiesced, - PVOID context - ); + _In_ AppChangeNotificationHandler routine + ) noexcept; void RemoveAppChangeNotificationHandler( _In_ XblFunctionContext token ) noexcept; #endif - // TODO making this a wrapper of xsapi_singleton for now. It properly manages the lifetime of the global state - // and enables asyncronous cleanup. Goal is to eventually move the necessary state from xsapi_singleton into this class - // and get rid of xsapi_singleton altogether. - std::shared_ptr singleton; +#if HC_PLATFORM == HC_PLATFORM_XDK + // On XDK, offline achievements are driven by ETX. + // The AchievementsService will create one ETX provider per XSAPI session (when needed) using these properties. + const String& AchievementsProviderName() const noexcept; + const GUID& AchievementsSessionId() const noexcept; +#endif + + const String& Locales() const noexcept; + void OverrideLocales(String&& locales) noexcept; + + // API Type to be used in HTTP requests so they are identifiable in traces. + // TODO consider configuring this with XblInitArgs + XblApiType ApiType{ XblApiType::XblCApi }; #if TRACK_ASYNC std::mutex asyncBlocksMutex{}; @@ -121,9 +118,23 @@ private: std::shared_ptr m_rtaManager; std::shared_ptr m_localStorage; Set m_userExpiredTokens; + UnorderedMap> m_userChangeHandlers; XblFunctionContext m_nextHandlerToken{ 0 }; - xsapi_internal_unordered_map> m_callRoutedHandlers; + UnorderedMap> m_callRoutedHandlers; + + String m_locales{ "en-US" }; + + // from Shared\xbox_live_app_config.cpp + const std::shared_ptr m_appConfig; + + // from Shared\Logger\log.cpp + const std::shared_ptr m_logger; + +#if HC_PLATFORM == HC_PLATFORM_XDK + String m_achivementsEventProviderName; + GUID m_achievementsSessionId{}; +#endif #if HC_PLATFORM == HC_PLATFORM_GDK XblFunctionContext m_nextAppChangeHandlerToken{ 0 }; @@ -147,7 +158,12 @@ private: #if HC_PLATFORM == HC_PLATFORM_GDK // Holds the registration ID for receiving App State Notifications (aka Quick Resume) - PAPPSTATE_REGISTRATION m_registrationID; + PAPPSTATE_REGISTRATION m_registrationID; + + static void AppStateChangeNotificationReceived( + BOOLEAN quiesced, + PVOID context + ); #endif }; diff --git a/Source/Shared/http_call_legacy.cpp b/Source/Shared/http_call_legacy.cpp index 851234dc..4e853b26 100644 --- a/Source/Shared/http_call_legacy.cpp +++ b/Source/Shared/http_call_legacy.cpp @@ -324,6 +324,10 @@ void http_call::set_request_body( uint8_t* buffer{ nullptr }; auto neededSize = value.size(); std::copy(value.begin(), value.end(), buffer); + if (buffer == nullptr) + { + return; + } XblHttpCallRequestSetRequestBodyBytes(m_callHandle, buffer, static_cast(neededSize)); } diff --git a/Source/Shared/http_call_legacy.h b/Source/Shared/http_call_legacy.h index 8c000cf1..75c34e08 100644 --- a/Source/Shared/http_call_legacy.h +++ b/Source/Shared/http_call_legacy.h @@ -109,7 +109,7 @@ private: web::json::value m_responseBodyJson; std::vector m_responseBodyVector; web::http::http_headers m_responseHeaders; - uint32_t m_httpStatus; + uint32_t m_httpStatus{ 0 }; std::error_code m_errorCode; std::string m_errMessage; @@ -242,8 +242,8 @@ private: string_t m_httpMethod; string_t m_serverName; web::uri m_pathQueryFragment; - bool m_longHttpCall; - bool m_retryAllowed; + bool m_longHttpCall{ false }; + bool m_retryAllowed{ false }; }; } diff --git a/Source/Shared/http_call_request_message.cpp b/Source/Shared/http_call_request_message.cpp index e7cb7f83..8f1274ac 100644 --- a/Source/Shared/http_call_request_message.cpp +++ b/Source/Shared/http_call_request_message.cpp @@ -19,16 +19,16 @@ http_call_request_message::http_call_request_message( ) : m_httpRequestMessageType(internalObj->get_http_request_message_type()) { - m_requestMessageString = utils::string_t_from_internal_string(internalObj->request_message_string()); - m_requestMessageVector = utils::std_vector_from_internal_vector(internalObj->request_message_vector()); + m_requestMessageString = internalObj->request_message_string(); + m_requestMessageVector = internalObj->request_message_vector(); } -const string_t& http_call_request_message::request_message_string() const +const xsapi_internal_string& http_call_request_message::request_message_string() const { return m_requestMessageString; } -const std::vector& http_call_request_message::request_message_vector() const +const xsapi_internal_vector& http_call_request_message::request_message_vector() const { return m_requestMessageVector; } diff --git a/Source/Shared/http_call_request_message_internal.h b/Source/Shared/http_call_request_message_internal.h index d5d789ca..884c2882 100644 --- a/Source/Shared/http_call_request_message_internal.h +++ b/Source/Shared/http_call_request_message_internal.h @@ -69,12 +69,12 @@ public: /// /// The http request message if it is a string type. /// - inline _XSAPIIMP const string_t& request_message_string() const; + inline _XSAPIIMP const xsapi_internal_string& request_message_string() const; /// /// The http request message if it is a buffer. /// - inline _XSAPIIMP const std::vector& request_message_vector() const; + inline _XSAPIIMP const xsapi_internal_vector& request_message_vector() const; /// /// The type of message. @@ -82,8 +82,8 @@ public: inline _XSAPIIMP http_request_message_type get_http_request_message_type() const; private: - std::vector m_requestMessageVector; - string_t m_requestMessageString; + xsapi_internal_vector m_requestMessageVector; + xsapi_internal_string m_requestMessageString; http_request_message_type m_httpRequestMessageType; }; diff --git a/Source/Shared/http_call_wrapper_internal.cpp b/Source/Shared/http_call_wrapper_internal.cpp index 30042e68..e56c7e8c 100644 --- a/Source/Shared/http_call_wrapper_internal.cpp +++ b/Source/Shared/http_call_wrapper_internal.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "xbox_live_context_internal.h" -#include "xbox_system_factory.h" #include using namespace xbox::services; @@ -46,7 +45,7 @@ HRESULT HttpCall::SetHeader( return HCHttpCallRequestSetHeader(m_callHandle, key.data(), value.data(), allowTracing); } -HRESULT HttpCall::SetRequestBody(xsapi_internal_vector&& bytes) +HRESULT HttpCall::SetRequestBody(const xsapi_internal_vector& bytes) { assert(m_step == Step::Pending); return HCHttpCallRequestSetRequestBodyBytes(m_callHandle, bytes.data(), static_cast(bytes.size())); @@ -117,7 +116,17 @@ HRESULT HttpCall::Perform( { m_performAlreadyCalled = true; m_step = Step::Running; - hr = HCHttpCallPerformAsync(m_callHandle, &m_asyncBlock); + + if (XblShouldFaultInject(INJECTION_FEATURE_HTTP)) + { + LOGS_ERROR << "FAULT INJECTION: HttpCall::Perform ID:" << XblGetFaultCounter(); + hr = E_FAIL; + } + else + { + hr = HCHttpCallPerformAsync(m_callHandle, &m_asyncBlock); + } + if (SUCCEEDED(hr)) { AddRef(); // Keep HttpCall object alive until call completes @@ -290,6 +299,13 @@ HRESULT HttpCall::Result() const uint32_t platformNetworkResult{ 0 }; RETURN_HR_IF_FAILED(HCHttpCallResponseGetNetworkErrorCode(m_callHandle, &hrNetworkError, &platformNetworkResult)); + + if (XblShouldFaultInject(INJECTION_FEATURE_HTTP)) + { + LOGS_ERROR << "FAULT INJECTION: HttpCall::Result" << XblGetFaultCounter(); + hrNetworkError = E_FAIL; + } + if (SUCCEEDED(hrNetworkError)) { HRESULT hrHttpStatus = ConvertHttpStatusToHRESULT(HttpStatus()); @@ -555,11 +571,11 @@ HRESULT XblHttpCall::Init( XblApiType apiType{ XblApiType::XblCApi }; { - auto singleton{ get_xsapi_singleton() }; + auto state{ GlobalState::Get() }; - if (singleton) + if (state) { - apiType = singleton->m_apiType; + apiType = state->ApiType; } } @@ -610,7 +626,7 @@ HRESULT XblHttpCall::SetHeader( return HttpCall::SetHeader(key, value, allowTracing); } -HRESULT XblHttpCall::SetRequestBody(xsapi_internal_vector&& bytes) +HRESULT XblHttpCall::SetRequestBody(const xsapi_internal_vector& bytes) { m_requestBody = bytes; return HttpCall::SetRequestBody(xsapi_internal_vector{ bytes }); @@ -630,7 +646,8 @@ HRESULT XblHttpCall::SetRequestBody(_In_z_ const char* requestBodyString) HRESULT XblHttpCall::SetRequestBody(const xsapi_internal_string& bodyString) { - return SetRequestBody(xsapi_internal_vector{ bodyString.begin(), bodyString.end() }); + m_requestBody = xsapi_internal_vector{ bodyString.begin(), bodyString.end() }; + return HttpCall::SetRequestBody(bodyString); } HRESULT XblHttpCall::SetRequestBody(const JsonValue& bodyJson) diff --git a/Source/Shared/http_call_wrapper_internal.h b/Source/Shared/http_call_wrapper_internal.h index 79ad1a02..88ae12f0 100644 --- a/Source/Shared/http_call_wrapper_internal.h +++ b/Source/Shared/http_call_wrapper_internal.h @@ -62,6 +62,7 @@ enum class xbox_live_api get_quota, get_quota_for_session_storage, get_search_handles, + delete_search_handle, get_session_host_allocation_status, get_sessions, get_single_user_statistics, @@ -100,7 +101,6 @@ enum class xbox_live_api xbox_one_pins_contains_item, xbox_one_pins_remove_item, post_recent_players, - update_activity, get_activity_batch, delete_activity, mpa_send_invites @@ -128,7 +128,7 @@ public: ); virtual HRESULT SetTracing(bool traceCall); - virtual HRESULT SetRequestBody(xsapi_internal_vector&& bytes); + virtual HRESULT SetRequestBody(const xsapi_internal_vector& bytes); virtual HRESULT SetRequestBody(_In_reads_bytes_(requestBodySize) const uint8_t* requestBodyBytes, _In_ uint32_t requestBodySize); virtual HRESULT SetRequestBody(const xsapi_internal_string& bodyString); virtual HRESULT SetRequestBody(const JsonValue& bodyJson); @@ -228,7 +228,7 @@ public: void SetLongHttpCall(_In_ bool longHttpCall); HRESULT SetXblServiceContractVersion(uint32_t contractVersion); - HRESULT SetRequestBody(xsapi_internal_vector&& bytes) override; + HRESULT SetRequestBody(const xsapi_internal_vector& bytes) override; HRESULT SetRequestBody(_In_reads_bytes_(requestBodySize) const uint8_t* requestBodyBytes, _In_ uint32_t requestBodySize) override; HRESULT SetRequestBody(const xsapi_internal_string& bodyString) override; HRESULT SetRequestBody(const JsonValue& bodyJson) override; diff --git a/Source/Shared/http_utils.cpp b/Source/Shared/http_utils.cpp index 7a5c980e..e8ab3233 100644 --- a/Source/Shared/http_utils.cpp +++ b/Source/Shared/http_utils.cpp @@ -62,8 +62,8 @@ namespace services { namespace detail { - string_t _to_base64(const unsigned char *ptr, size_t size); - std::vector _from_base64(const string_t& str); + xsapi_internal_string _to_base64(const unsigned char *ptr, size_t size); + std::vector _from_base64(const xsapi_internal_string& str); struct _triple_byte { @@ -86,9 +86,9 @@ namespace detail 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255 } }; - string_t _to_base64(const unsigned char *ptr, size_t size) + xsapi_internal_string _to_base64(const unsigned char *ptr, size_t size) { - string_t result; + xsapi_internal_string result; for (; size >= 3; ) { @@ -97,10 +97,10 @@ namespace detail unsigned char idx1 = (record->_1_1 << 4) | record->_1_2; unsigned char idx2 = (record->_2_1 << 2) | record->_2_2; unsigned char idx3 = record->_3; - result.push_back(char_t(_base64_enctbl[idx0])); - result.push_back(char_t(_base64_enctbl[idx1])); - result.push_back(char_t(_base64_enctbl[idx2])); - result.push_back(char_t(_base64_enctbl[idx3])); + result.push_back(char(_base64_enctbl[idx0])); + result.push_back(char(_base64_enctbl[idx1])); + result.push_back(char(_base64_enctbl[idx2])); + result.push_back(char(_base64_enctbl[idx3])); size -= 3; ptr += 3; } @@ -111,8 +111,8 @@ namespace detail const _triple_byte* record = reinterpret_cast(ptr); unsigned char idx0 = record->_0; unsigned char idx1 = (record->_1_1 << 4); - result.push_back(char_t(_base64_enctbl[idx0])); - result.push_back(char_t(_base64_enctbl[idx1])); + result.push_back(char(_base64_enctbl[idx0])); + result.push_back(char(_base64_enctbl[idx1])); result.push_back('='); result.push_back('='); break; @@ -123,9 +123,9 @@ namespace detail unsigned char idx0 = record->_0; unsigned char idx1 = (record->_1_1 << 4) | record->_1_2; unsigned char idx2 = (record->_2_1 << 2); - result.push_back(char_t(_base64_enctbl[idx0])); - result.push_back(char_t(_base64_enctbl[idx1])); - result.push_back(char_t(_base64_enctbl[idx2])); + result.push_back(char(_base64_enctbl[idx0])); + result.push_back(char(_base64_enctbl[idx1])); + result.push_back(char(_base64_enctbl[idx2])); result.push_back('='); break; } @@ -145,7 +145,7 @@ namespace detail // gcc is concerned about the bitfield uses in the code, something we simply need to ignore. #pragma GCC diagnostic ignored "-Wconversion" #endif - std::vector _from_base64(const string_t& input) + std::vector _from_base64(const xsapi_internal_string& input) { std::vector result; @@ -192,7 +192,7 @@ namespace detail auto size = input.size(); - const char_t* ptr = &input[0]; + const char* ptr = &input[0]; auto outsz = (size / 4) * 3; outsz -= padding; @@ -235,7 +235,10 @@ namespace detail memset(target, 0, sizeof(target)); _triple_byte* record = reinterpret_cast<_triple_byte*>(target); + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_EXPRESSION_NOT_TRUE; unsigned char val0 = _base64_dectbl[ptr[0]]; + DISABLE_WARNING_POP; unsigned char val1 = _base64_dectbl[ptr[1]]; unsigned char val2 = _base64_dectbl[ptr[2]]; unsigned char val3 = _base64_dectbl[ptr[3]]; @@ -292,7 +295,7 @@ namespace detail } #endif - static bool is_digit(char_t c) { return c >= _XPLATSTR('0') && c <= _XPLATSTR('9'); } + static bool is_digit(char c) { return c >= '0' && c <= '9'; } datetime datetime::utc_now() { @@ -312,7 +315,7 @@ namespace detail #endif } - string_t datetime::to_string(date_format format) const + xsapi_internal_string datetime::to_string(date_format format) const { #ifdef _WIN32 int status; @@ -330,7 +333,7 @@ namespace detail throw details::create_system_error(GetLastError()); } - std::wostringstream outStream; + xsapi_internal_wostringstream outStream; outStream.imbue(std::locale::classic()); if (format == RFC_1123) @@ -403,7 +406,8 @@ namespace detail outStream << "Z"; } - return outStream.str(); + auto result = convert::utf16_to_utf8_internal(outStream.str()); + return result; #else //LINUX uint64_t input = m_interval; uint64_t frac_sec = input % _secondTicks; @@ -437,7 +441,7 @@ namespace detail &datetime); } - return std::string(output); + return xsapi_internal_string(output); #endif } @@ -459,7 +463,7 @@ namespace detail return ufrac_second; } - void extract_fractional_second(const string_t& dateString, string_t& resultString, uint64_t& ufrac_second) + void extract_fractional_second(const xsapi_internal_string& dateString, xsapi_internal_string& resultString, uint64_t& ufrac_second) { resultString = dateString; // First, the string must be strictly longer than 2 characters, and the trailing character must be 'Z' @@ -505,7 +509,7 @@ namespace detail } #endif - datetime datetime::from_string(const string_t& dateString, date_format format) + datetime datetime::from_string(const xsapi_internal_string& dateString, date_format format) { // avoid floating point math to preserve precision uint64_t ufrac_second = 0; @@ -516,11 +520,11 @@ namespace detail { SYSTEMTIME sysTime = { 0 }; - std::wstring month(3, L'\0'); - std::wstring unused(3, L'\0'); + xsapi_internal_string month(3, '\0'); + xsapi_internal_string unused(3, '\0'); - const wchar_t* formatString = L"%3c, %2d %3c %4d %2d:%2d:%2d %3c"; - auto n = swscanf_s(dateString.c_str(), formatString, + const char* formatString = "%3c, %2d %3c %4d %2d:%2d:%2d %3c"; + auto n = sscanf_s(dateString.c_str(), formatString, unused.data(), unused.size(), &sysTime.wDay, month.data(), month.size(), @@ -532,8 +536,8 @@ namespace detail if (n == 8) { - std::wstring monthnames[12] = { L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec" }; - auto loc = std::find_if(monthnames, monthnames + 12, [&month](const std::wstring& m) { return m == month; }); + xsapi_internal_string monthnames[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + auto loc = std::find_if(monthnames, monthnames + 12, [&month](const xsapi_internal_string& m) { return m == month; }); if (loc != monthnames + 12) { @@ -551,12 +555,12 @@ namespace detail // increments. Therefore, start with seconds and milliseconds set to 0, then add them separately // Try to extract the fractional second from the timestamp - string_t input; + xsapi_internal_string input; extract_fractional_second(dateString, input, ufrac_second); { SYSTEMTIME sysTime = { 0 }; - const wchar_t* formatString = L"%4d-%2d-%2dT%2d:%2d:%2dZ"; - auto n = swscanf_s(input.c_str(), formatString, + const char* formatString = "%4d-%2d-%2dT%2d:%2d:%2dZ"; + auto n = sscanf_s(input.c_str(), formatString, &sysTime.wYear, &sysTime.wMonth, &sysTime.wDay, @@ -576,8 +580,8 @@ namespace detail SYSTEMTIME sysTime = { 0 }; DWORD date = 0; - const wchar_t* formatString = L"%8dT%2d:%2d:%2dZ"; - auto n = swscanf_s(input.c_str(), formatString, + const char* formatString = "%8dT%2d:%2d:%2dZ"; + auto n = sscanf_s(input.c_str(), formatString, &date, &sysTime.wHour, &sysTime.wMinute, @@ -603,8 +607,8 @@ namespace detail sysTime.wSecond = 0; sysTime.wMilliseconds = 0; - const wchar_t* formatString = L"%2d:%2d:%2dZ"; - auto n = swscanf_s(input.c_str(), formatString, + const char* formatString = "%2d:%2d:%2dZ"; + auto n = sscanf_s(input.c_str(), formatString, &sysTime.wHour, &sysTime.wMinute, &sysTime.wSecond); @@ -621,7 +625,7 @@ namespace detail return datetime(); #else - std::string input(dateString); + xsapi_internal_string input(dateString); struct tm output = tm(); @@ -632,7 +636,7 @@ namespace detail else { // Try to extract the fractional second from the timestamp - string_t input; + xsapi_internal_string input; extract_fractional_second(dateString, input, ufrac_second); auto result = strptime(input.data(), "%Y-%m-%dT%H:%M:%SZ", &output); @@ -680,7 +684,7 @@ namespace detail static std::mutex env_var_lock; { std::lock_guard lock(env_var_lock); - std::string prev_env; + xsapi_internal_string prev_env; auto prev_env_cstr = getenv("TZ"); if (prev_env_cstr != nullptr) { @@ -728,13 +732,13 @@ namespace detail #define H_SURROGATE_END 0xDBFF #define SURROGATE_PAIR_START 0x10000 - utf16string convert::utf8_to_utf16(const std::string &s) + xsapi_internal_wstring convert::utf8_to_utf16(const xsapi_internal_string &s) { #if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) std::wstring_convert, utf16char> conversion; return conversion.from_bytes(s); #else - utf16string dest; + xsapi_internal_wstring dest; // Save repeated heap allocations, use less than source string size assuming some // of the characters are not just ASCII and collapse. dest.reserve(static_cast(static_cast(s.size()) * .70)); @@ -743,7 +747,7 @@ namespace detail { if ((*src & BIT8) == 0) // single byte character, 0x0 to 0x7F { - dest.push_back(utf16string::value_type(*src)); + dest.push_back(xsapi_internal_wstring::value_type(*src)); } else { @@ -794,15 +798,15 @@ namespace detail // - high surrogate is 0xD800 added to the top ten bits // - low surrogate is 0xDC00 added to the low ten bits codePoint -= SURROGATE_PAIR_START; - dest.push_back(utf16string::value_type((codePoint >> 10) | H_SURROGATE_START)); - dest.push_back(utf16string::value_type((codePoint & 0x3FF) | L_SURROGATE_START)); + dest.push_back(xsapi_internal_wstring::value_type((codePoint >> 10) | H_SURROGATE_START)); + dest.push_back(xsapi_internal_wstring::value_type((codePoint & 0x3FF) | L_SURROGATE_START)); } else { // In UTF-16 U+0000 to U+D7FF and U+E000 to U+FFFF are represented exactly as the Unicode code point value. // U+D800 to U+DFFF are not valid characters, for simplicity we assume they are not present but will encode // them if encountered. - dest.push_back(utf16string::value_type(codePoint)); + dest.push_back(xsapi_internal_wstring::value_type(codePoint)); } } } @@ -810,11 +814,11 @@ namespace detail #endif } - std::string convert::to_utf8string(std::string value) { return value; } + xsapi_internal_string convert::to_utf8string(xsapi_internal_string value) { return value; } - std::string convert::to_utf8string(const utf16string &value) { return utf16_to_utf8(value); } + xsapi_internal_string convert::to_utf8string(const xsapi_internal_wstring &value) { return utf16_to_utf8_internal(value); } - std::string convert::utf16_to_utf8(const utf16string &w) + std::string convert::utf16_to_utf8(const std::wstring &w) { #if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) std::wstring_convert, utf16char> conversion; @@ -878,16 +882,71 @@ namespace detail #endif } - string_t convert::to_string_t(const std::string &s) + xsapi_internal_string convert::utf16_to_utf8_internal(const xsapi_internal_wstring &w) { -#ifdef _UTF16_STRINGS - return utf8_to_utf16(s); +#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS) + std::wstring_convert, utf16char> conversion; + return conversion.to_bytes(w); #else - return s; + xsapi_internal_string dest; + dest.reserve(w.size()); + for (auto src = w.begin(); src != w.end(); ++src) + { + // Check for high surrogate. + if (*src >= H_SURROGATE_START && *src <= H_SURROGATE_END) + { + const auto highSurrogate = *src++; + if (src == w.end()) + { + throw std::range_error("UTF-16 string is missing low surrogate"); + } + const auto lowSurrogate = *src; + if (lowSurrogate < L_SURROGATE_START || lowSurrogate > L_SURROGATE_END) + { + throw std::range_error("UTF-16 string has invalid low surrogate"); + } + + // To get from surrogate pair to Unicode code point: + // - subract 0xD800 from high surrogate, this forms top ten bits + // - subract 0xDC00 from low surrogate, this forms low ten bits + // - add 0x10000 + // Leaves a code point in U+10000 to U+10FFFF range. + uint32_t codePoint = highSurrogate - H_SURROGATE_START; + codePoint <<= 10; + codePoint |= lowSurrogate - L_SURROGATE_START; + codePoint += SURROGATE_PAIR_START; + + // 4 bytes need using 21 bits + dest.push_back(char((codePoint >> 18) | 0xF0)); // leading 3 bits + dest.push_back(char(((codePoint >> 12) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char(((codePoint >> 6) & LOW_6BITS) | BIT8)); // next 6 bits + dest.push_back(char((codePoint & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else + { + if (*src <= 0x7F) // single byte character + { + dest.push_back(static_cast(*src)); + } + else if (*src <= 0x7FF) // 2 bytes needed (11 bits used) + { + dest.push_back(char((*src >> 6) | 0xC0)); // leading 5 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + else // 3 bytes needed (16 bits used) + { + dest.push_back(char((*src >> 12) | 0xE0)); // leading 4 bits + dest.push_back(char(((*src >> 6) & LOW_6BITS) | BIT8)); // middle 6 bits + dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits + } + } + } + + return dest; #endif } - String convert::to_base64(const Vector& input) + xsapi_internal_string convert::to_base64(const Vector& input) { if (input.size() == 0) { @@ -895,10 +954,10 @@ namespace detail return String(); } - return utils::internal_string_from_string_t(detail::_to_base64(&input[0], input.size())); + return detail::_to_base64(&input[0], input.size()); } - std::vector convert::from_base64(const string_t& str) + std::vector convert::from_base64(const xsapi_internal_string& str) { return detail::_from_base64(str); } @@ -931,6 +990,7 @@ namespace detail std::string windows_category_impl::message(int errorCode) const CPPREST_NOEXCEPT { +#if 0 // this returns a non-mem hooked string which can't be changed so commenting it out since its not really needed const size_t buffer_size = 4096; DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM; LPCVOID lpSource = NULL; @@ -960,8 +1020,11 @@ namespace detail os << "Unable to get an error message for error code: " << errorCode << "."; return os.str(); } - return convert::to_utf8string(buffer); +#else + UNREFERENCED_PARAMETER(errorCode); + return std::string(); +#endif } std::error_condition windows_category_impl::default_error_condition(int errorCode) const CPPREST_NOEXCEPT @@ -1023,61 +1086,63 @@ namespace services { namespace details { - string_t uri_components::join() + xsapi_internal_string uri_components::join() { // canonicalize components first // convert scheme to lowercase - std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), [](char_t c) { - return (char_t)tolower(c); + std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), [](char c) { + return (char)tolower(c); }); // convert host to lowercase - std::transform(m_host.begin(), m_host.end(), m_host.begin(), [](char_t c) { - return (char_t)tolower(c); + std::transform(m_host.begin(), m_host.end(), m_host.begin(), [](char c) { + return (char)tolower(c); }); // canonicalize the path to have a leading slash if it's a full uri if (!m_host.empty() && m_path.empty()) { - m_path = _XPLATSTR("/"); + m_path = "/"; } - else if (!m_host.empty() && m_path[0] != _XPLATSTR('/')) + else if (!m_host.empty() && m_path[0] != '/') { - m_path.insert(m_path.begin(), 1, _XPLATSTR('/')); + m_path.insert(m_path.begin(), 1, '/'); } - string_t ret; + xsapi_internal_string ret; #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) if (!m_scheme.empty()) { - ret.append(m_scheme).append({ _XPLATSTR(':') }); + ret.append(m_scheme).append({ ':' }); } if (!m_host.empty()) { - ret.append(_XPLATSTR("//")); + ret.append("//"); if (!m_user_info.empty()) { - ret.append(m_user_info).append({ _XPLATSTR('@') }); + ret.append(m_user_info).append({ '@' }); } ret.append(m_host); if (m_port > 0) { - ret.append({ _XPLATSTR(':') }).append(convert::print_string(m_port, std::locale::classic())); + char buf[16] = { 0 }; + sprintf_s(buf, sizeof(buf), ":%d", m_port); + ret.append(buf); } } if (!m_path.empty()) { // only add the leading slash when the host is present - if (!m_host.empty() && m_path.front() != _XPLATSTR('/')) + if (!m_host.empty() && m_path.front() != '/') { - ret.append({ _XPLATSTR('/') }); + ret.append({ '/' }); } ret.append(m_path); @@ -1085,59 +1150,59 @@ namespace services if (!m_query.empty()) { - ret.append({ _XPLATSTR('?') }).append(m_query); + ret.append({ '?' }).append(m_query); } if (!m_fragment.empty()) { - ret.append({ _XPLATSTR('#') }).append(m_fragment); + ret.append({ '#' }).append(m_fragment); } return ret; #else - ostringstream_t os; + xsapi_internal_ostringstream_t os; os.imbue(std::locale::classic()); if (!m_scheme.empty()) { - os << m_scheme << _XPLATSTR(':'); + os << m_scheme << ':'; } if (!m_host.empty()) { - os << _XPLATSTR("//"); + os << "//"; if (!m_user_info.empty()) { - os << m_user_info << _XPLATSTR('@'); + os << m_user_info << '@'; } os << m_host; if (m_port > 0) { - os << _XPLATSTR(':') << m_port; + os << ':' << m_port; } } if (!m_path.empty()) { // only add the leading slash when the host is present - if (!m_host.empty() && m_path.front() != _XPLATSTR('/')) + if (!m_host.empty() && m_path.front() != '/') { - os << _XPLATSTR('/'); + os << '/'; } os << m_path; } if (!m_query.empty()) { - os << _XPLATSTR('?') << m_query; + os << '?' << m_query; } if (!m_fragment.empty()) { - os << _XPLATSTR('#') << m_fragment; + os << '#' << m_fragment; } return os.str(); @@ -1147,21 +1212,21 @@ namespace services namespace uri_parser { - bool validate(const string_t& encoded_string) + bool validate(const xsapi_internal_string& encoded_string) { - const char_t* scheme_begin = nullptr; - const char_t* scheme_end = nullptr; - const char_t* uinfo_begin = nullptr; - const char_t* uinfo_end = nullptr; - const char_t* host_begin = nullptr; - const char_t* host_end = nullptr; + const char* scheme_begin = nullptr; + const char* scheme_end = nullptr; + const char* uinfo_begin = nullptr; + const char* uinfo_end = nullptr; + const char* host_begin = nullptr; + const char* host_end = nullptr; int port_ptr = 0; - const char_t* path_begin = nullptr; - const char_t* path_end = nullptr; - const char_t* query_begin = nullptr; - const char_t* query_end = nullptr; - const char_t* fragment_begin = nullptr; - const char_t* fragment_end = nullptr; + const char* path_begin = nullptr; + const char* path_end = nullptr; + const char* query_begin = nullptr; + const char* query_end = nullptr; + const char* fragment_begin = nullptr; + const char* fragment_end = nullptr; // perform a parse, but don't copy out the data return inner_parse( @@ -1181,21 +1246,21 @@ namespace services &fragment_end); } - bool parse(const string_t& encoded_string, uri_components& components) + bool parse(const xsapi_internal_string& encoded_string, uri_components& components) { - const char_t* scheme_begin = nullptr; - const char_t* scheme_end = nullptr; - const char_t* host_begin = nullptr; - const char_t* host_end = nullptr; - const char_t* uinfo_begin = nullptr; - const char_t* uinfo_end = nullptr; + const char* scheme_begin = nullptr; + const char* scheme_end = nullptr; + const char* host_begin = nullptr; + const char* host_end = nullptr; + const char* uinfo_begin = nullptr; + const char* uinfo_end = nullptr; int port_ptr = 0; - const char_t* path_begin = nullptr; - const char_t* path_end = nullptr; - const char_t* query_begin = nullptr; - const char_t* query_end = nullptr; - const char_t* fragment_begin = nullptr; - const char_t* fragment_end = nullptr; + const char* path_begin = nullptr; + const char* path_end = nullptr; + const char* query_begin = nullptr; + const char* query_end = nullptr; + const char* fragment_begin = nullptr; + const char* fragment_end = nullptr; if (inner_parse( encoded_string.c_str(), @@ -1218,8 +1283,8 @@ namespace services components.m_scheme.assign(scheme_begin, scheme_end); // convert scheme to lowercase - std::transform(components.m_scheme.begin(), components.m_scheme.end(), components.m_scheme.begin(), [](char_t c) { - return (char_t)tolower(c); + std::transform(components.m_scheme.begin(), components.m_scheme.end(), components.m_scheme.begin(), [](char c) { + return (char)tolower(c); }); } else @@ -1237,8 +1302,8 @@ namespace services components.m_host.assign(host_begin, host_end); // convert host to lowercase - std::transform(components.m_host.begin(), components.m_host.end(), components.m_host.begin(), [](char_t c) { - return (char_t)tolower(c); + std::transform(components.m_host.begin(), components.m_host.end(), components.m_host.begin(), [](char c) { + return (char)tolower(c); }); } else @@ -1262,7 +1327,7 @@ namespace services else { // default path to begin with a slash for easy comparison - components.m_path = _XPLATSTR("/"); + components.m_path = "/"; } if (query_begin) @@ -1292,14 +1357,14 @@ namespace services } bool inner_parse( - const char_t* encoded, - const char_t** scheme_begin, const char_t** scheme_end, - const char_t** uinfo_begin, const char_t** uinfo_end, - const char_t** host_begin, const char_t** host_end, + const char* encoded, + const char** scheme_begin, const char** scheme_end, + const char** uinfo_begin, const char** uinfo_end, + const char** host_begin, const char** host_end, _Out_ int* port, - const char_t** path_begin, const char_t** path_end, - const char_t** query_begin, const char_t** query_end, - const char_t** fragment_begin, const char_t** fragment_end) + const char** path_begin, const char** path_end, + const char** query_begin, const char** query_end, + const char** fragment_begin, const char** fragment_end) { *scheme_begin = nullptr; *scheme_end = nullptr; @@ -1315,7 +1380,7 @@ namespace services *fragment_begin = nullptr; *fragment_end = nullptr; - const char_t* p = encoded; + const char* p = encoded; // IMPORTANT -- A uri may either be an absolute uri, or an relative-reference // Absolute: 'http://host.com' @@ -1323,10 +1388,10 @@ namespace services // A Relative-Reference can be disambiguated by parsing for a ':' before the first slash bool is_relative_reference = true; - const char_t* p2 = p; - for (; *p2 != _XPLATSTR('/') && *p2 != _XPLATSTR('\0'); p2++) + const char* p2 = p; + for (; *p2 != '/' && *p2 != '\0'; p2++) { - if (*p2 == _XPLATSTR(':')) + if (*p2 == ':') { // found a colon, the first portion is a scheme is_relative_reference = false; @@ -1359,9 +1424,9 @@ namespace services // if we see two slashes next, then we're going to parse the authority portion // later on we'll break up the authority into the port and host - const char_t* authority_begin = nullptr; - const char_t* authority_end = nullptr; - if (*p == _XPLATSTR('/') && p[1] == _XPLATSTR('/')) + const char* authority_begin = nullptr; + const char* authority_end = nullptr; + if (*p == '/' && p[1] == '/') { // skip over the slashes p += 2; @@ -1369,7 +1434,7 @@ namespace services // the authority is delimited by a slash (resource), question-mark (query) or octothorpe (fragment) // or by EOS. The authority could be empty ('file:///C:\file_name.txt') - for (; *p != _XPLATSTR('/') && *p != _XPLATSTR('?') && *p != _XPLATSTR('#') && *p != _XPLATSTR('\0'); p++) + for (; *p != '/' && *p != '?' && *p != '#' && *p != '\0'; p++) { // We're NOT currently supporting IPv6, IPvFuture or username/password in authority if (!is_authority_character(*p)) @@ -1383,12 +1448,12 @@ namespace services if (authority_begin != authority_end) { // the port is made up of all digits - const char_t* port_begin = authority_end - 1; + const char* port_begin = authority_end - 1; for (; isdigit(*port_begin) && port_begin != authority_begin; port_begin--) { } - if (*port_begin == _XPLATSTR(':')) + if (*port_begin == ':') { // has a port *host_begin = authority_begin; @@ -1397,7 +1462,7 @@ namespace services //skip the colon port_begin++; - *port = convert::scan_string(string_t(port_begin, authority_end), std::locale::classic()); + *port = convert::scan_string(xsapi_internal_string(port_begin, authority_end), std::locale::classic()); } else { @@ -1407,12 +1472,12 @@ namespace services } // look for a user_info component - const char_t* u_end = *host_begin; + const char* u_end = *host_begin; for (; is_user_info_character(*u_end) && u_end != *host_end; u_end++) { } - if (*u_end == _XPLATSTR('@')) + if (*u_end == '@') { *host_begin = u_end + 1; *uinfo_begin = authority_begin; @@ -1427,12 +1492,12 @@ namespace services // if we see a path character or a slash, then the // if we see a slash, or any other legal path character, parse the path next - if (*p == _XPLATSTR('/') || is_path_character(*p)) + if (*p == '/' || is_path_character(*p)) { *path_begin = p; // the path is delimited by a question-mark (query) or octothorpe (fragment) or by EOS - for (; *p != _XPLATSTR('?') && *p != _XPLATSTR('#') && *p != _XPLATSTR('\0'); p++) + for (; *p != '?' && *p != '#' && *p != '\0'; p++) { if (!is_path_character(*p)) { @@ -1443,14 +1508,14 @@ namespace services } // if we see a ?, then the query is next - if (*p == _XPLATSTR('?')) + if (*p == '?') { // skip over the question mark p++; *query_begin = p; // the query is delimited by a '#' (fragment) or EOS - for (; *p != _XPLATSTR('#') && *p != _XPLATSTR('\0'); p++) + for (; *p != '#' && *p != '\0'; p++) { if (!is_query_character(*p)) { @@ -1461,14 +1526,14 @@ namespace services } // if we see a #, then the fragment is next - if (*p == _XPLATSTR('#')) + if (*p == '#') { // skip over the hash mark p++; *fragment_begin = p; // the fragment is delimited by EOS - for (; *p != _XPLATSTR('\0'); p++) + for (; *p != '\0'; p++) { if (!is_fragment_character(*p)) { @@ -1497,7 +1562,7 @@ namespace services } } - uri::uri(const string_t& uri_string) + uri::uri(const xsapi_internal_string& uri_string) { if (!details::uri_parser::parse(uri_string, m_components)) { @@ -1506,7 +1571,7 @@ namespace services m_uri = m_components.join(); } - uri::uri(const char_t* uri_string) : m_uri(uri_string) + uri::uri(const char* uri_string) : m_uri(uri_string) { if (!details::uri_parser::parse(uri_string, m_components)) { @@ -1515,11 +1580,10 @@ namespace services m_uri = m_components.join(); } - string_t uri::encode_impl(const string_t& raw, const std::function& should_encode) + xsapi_internal_string uri::encode_impl(const xsapi_internal_string& utf8raw, const std::function& should_encode) { - const char_t* const hex = _XPLATSTR("0123456789ABCDEF"); - string_t encoded; - std::string utf8raw = convert::to_utf8string(raw); + const char* const hex = "0123456789ABCDEF"; + xsapi_internal_string encoded; for (auto iter = utf8raw.begin(); iter != utf8raw.end(); ++iter) { // for utf8 encoded string, char ASCII can be greater than 127. @@ -1527,14 +1591,14 @@ namespace services // ch should be same under both utf8 and utf16. if (should_encode(ch)) { - encoded.push_back(_XPLATSTR('%')); + encoded.push_back('%'); encoded.push_back(hex[(ch >> 4) & 0xF]); encoded.push_back(hex[ch & 0xF]); } else { // ASCII don't need to be encoded, which should be same on both utf8 and utf16. - encoded.push_back((char_t)ch); + encoded.push_back((char)ch); } } return encoded; @@ -1544,7 +1608,7 @@ namespace services /// Encodes a string by converting all characters except for RFC 3986 unreserved characters to their /// hexadecimal representation. /// - string_t uri::encode_data_string(const string_t& raw) + xsapi_internal_string uri::encode_data_string(const xsapi_internal_string& raw) { return uri::encode_impl(raw, [](int ch) -> bool { @@ -1552,7 +1616,7 @@ namespace services }); } - string_t uri::encode_uri(const string_t& raw, uri::components::component component) + xsapi_internal_string uri::encode_uri(const xsapi_internal_string& raw, uri::components::component component) { // Note: we also encode the '+' character because some non-standard implementations // encode the space character as a '+' instead of %20. To better interoperate we encode @@ -1624,12 +1688,12 @@ namespace services return decimal; } - string_t uri::decode(const string_t& encoded) + xsapi_internal_string uri::decode(const xsapi_internal_string& encoded) { - std::string utf8raw; + xsapi_internal_string utf8raw; for (auto iter = encoded.begin(); iter != encoded.end(); ++iter) { - if (*iter == _XPLATSTR('%')) + if (*iter == '%') { if (++iter == encoded.end()) { @@ -1650,17 +1714,17 @@ namespace services utf8raw.push_back(reinterpret_cast(*iter)); } } - return convert::to_string_t(utf8raw); + return utf8raw; } - std::vector uri::split_path(const string_t& path) + std::vector uri::split_path(const xsapi_internal_string& path) { - std::vector results; - istringstream_t iss(path); + std::vector results; + xsapi_internal_istringstream iss(path); iss.imbue(std::locale::classic()); - string_t s; + xsapi_internal_string s; - while (std::getline(iss, s, _XPLATSTR('/'))) + while (std::getline(iss, s, '/')) { if (!s.empty()) { @@ -1671,37 +1735,37 @@ namespace services return results; } - std::map uri::split_query(const string_t& query) + std::map uri::split_query(const xsapi_internal_string& query) { - std::map results; + std::map results; // Split into key value pairs separated by '&'. size_t prev_amp_index = 0; - while (prev_amp_index != string_t::npos) + while (prev_amp_index != xsapi_internal_string::npos) { - size_t amp_index = query.find_first_of(_XPLATSTR('&'), prev_amp_index); - if (amp_index == string_t::npos) - amp_index = query.find_first_of(_XPLATSTR(';'), prev_amp_index); + size_t amp_index = query.find_first_of('&', prev_amp_index); + if (amp_index == xsapi_internal_string::npos) + amp_index = query.find_first_of(';', prev_amp_index); - string_t key_value_pair = query.substr( + xsapi_internal_string key_value_pair = query.substr( prev_amp_index, - amp_index == string_t::npos ? query.size() - prev_amp_index : amp_index - prev_amp_index); - prev_amp_index = amp_index == string_t::npos ? string_t::npos : amp_index + 1; + amp_index == xsapi_internal_string::npos ? query.size() - prev_amp_index : amp_index - prev_amp_index); + prev_amp_index = amp_index == xsapi_internal_string::npos ? xsapi_internal_string::npos : amp_index + 1; - size_t equals_index = key_value_pair.find_first_of(_XPLATSTR('=')); - if (equals_index == string_t::npos) + size_t equals_index = key_value_pair.find_first_of('='); + if (equals_index == xsapi_internal_string::npos) { continue; } else if (equals_index == 0) { - string_t value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); - results[_XPLATSTR("")] = value; + xsapi_internal_string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + results[""] = value; } else { - string_t key(key_value_pair.begin(), key_value_pair.begin() + equals_index); - string_t value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + xsapi_internal_string key(key_value_pair.begin(), key_value_pair.begin() + equals_index); + xsapi_internal_string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); results[key] = value; } } @@ -1709,7 +1773,7 @@ namespace services return results; } - bool uri::validate(const string_t& uri_string) + bool uri::validate(const xsapi_internal_string& uri_string) { return uri_parser::validate(uri_string); } @@ -1772,34 +1836,34 @@ namespace services } - uri_builder& uri_builder::append_path(const string_t& path, bool is_encode) + uri_builder& uri_builder::append_path(const xsapi_internal_string& path, bool is_encode) { - if (path.empty() || path == _XPLATSTR("/")) + if (path.empty() || path == "/") { return *this; } auto encoded_path = is_encode ? uri::encode_uri(path, uri::components::path) : path; auto thisPath = this->path(); - if (thisPath.empty() || thisPath == _XPLATSTR("/")) + if (thisPath.empty() || thisPath == "/") { - if (encoded_path.front() != _XPLATSTR('/')) + if (encoded_path.front() != '/') { - set_path(_XPLATSTR("/") + encoded_path); + set_path("/" + encoded_path); } else { set_path(encoded_path); } } - else if (thisPath.back() == _XPLATSTR('/') && encoded_path.front() == _XPLATSTR('/')) + else if (thisPath.back() == '/' && encoded_path.front() == '/') { thisPath.pop_back(); set_path(thisPath + encoded_path); } - else if (thisPath.back() != _XPLATSTR('/') && encoded_path.front() != _XPLATSTR('/')) + else if (thisPath.back() != '/' && encoded_path.front() != '/') { - set_path(thisPath + _XPLATSTR("/") + encoded_path); + set_path(thisPath + "/" + encoded_path); } else { @@ -1809,7 +1873,7 @@ namespace services return *this; } - uri_builder& uri_builder::append_query(const string_t& query, bool is_encode) + uri_builder& uri_builder::append_query(const xsapi_internal_string& query, bool is_encode) { if (query.empty()) { @@ -1822,14 +1886,14 @@ namespace services { this->set_query(encoded_query); } - else if (thisQuery.back() == _XPLATSTR('&') && encoded_query.front() == _XPLATSTR('&')) + else if (thisQuery.back() == '&' && encoded_query.front() == '&') { thisQuery.pop_back(); this->set_query(thisQuery + encoded_query); } - else if (thisQuery.back() != _XPLATSTR('&') && encoded_query.front() != _XPLATSTR('&')) + else if (thisQuery.back() != '&' && encoded_query.front() != '&') { - this->set_query(thisQuery + _XPLATSTR("&") + encoded_query); + this->set_query(thisQuery + "&" + encoded_query); } else { @@ -1847,7 +1911,7 @@ namespace services return *this; } - string_t uri_builder::to_string() + xsapi_internal_string uri_builder::to_string() { return to_uri().to_string(); } diff --git a/Source/Shared/http_utils.h b/Source/Shared/http_utils.h index 53843770..49ab2179 100644 --- a/Source/Shared/http_utils.h +++ b/Source/Shared/http_utils.h @@ -2,6 +2,7 @@ #include #include +#include #ifndef _WIN32 # define __STDC_LIMIT_MACROS @@ -64,7 +65,7 @@ namespace services typedef char utf8char; typedef std::string utf8string; - typedef std::stringstream utf8stringstream; + typedef xsapi_internal_stringstream utf8stringstream; typedef std::ostringstream utf8ostringstream; typedef std::ostream utf8ostream; typedef std::istream utf8istream; @@ -72,16 +73,12 @@ namespace services #ifdef _UTF16_STRINGS typedef wchar_t utf16char; - typedef std::wstring utf16string; - typedef std::wstringstream utf16stringstream; typedef std::wostringstream utf16ostringstream; typedef std::wostream utf16ostream; typedef std::wistream utf16istream; typedef std::wistringstream utf16istringstream; #else typedef char16_t utf16char; - typedef std::u16string utf16string; - typedef std::basic_stringstream utf16stringstream; typedef std::basic_ostringstream utf16ostringstream; typedef std::basic_ostream utf16ostream; typedef std::basic_istream utf16istream; @@ -133,12 +130,12 @@ namespace services /// Creates datetime from a string representing time in UTC in RFC 1123 format. /// /// Returns a datetime of zero if not successful. - static datetime from_string(const string_t& timestring, date_format format = RFC_1123); + static datetime from_string(const xsapi_internal_string& timestring, date_format format = RFC_1123); /// /// Returns a string representation of the datetime. /// - string_t to_string(date_format format = RFC_1123) const; + xsapi_internal_string to_string(date_format format = RFC_1123) const; /// /// Returns the integral time value. @@ -243,35 +240,36 @@ namespace services /// /// A two byte character UTF-16 string. /// A single byte character UTF-8 string. - std::string utf16_to_utf8(const utf16string &w); + xsapi_internal_string utf16_to_utf8_internal(const xsapi_internal_wstring &w); + std::string utf16_to_utf8(const std::wstring &w); /// /// Converts a UTF-8 string to a UTF-16 /// /// A single byte character UTF-8 string. /// A two byte character UTF-16 string. - utf16string utf8_to_utf16(const std::string &s); + xsapi_internal_wstring utf8_to_utf16(const xsapi_internal_string &s); /// /// Converts to a UTF-8 string. /// /// A single byte character UTF-8 string. /// A single byte character UTF-8 string. - std::string to_utf8string(std::string value); + xsapi_internal_string to_utf8string(xsapi_internal_string value); /// /// Converts to a UTF-8 string. /// /// A two byte character UTF-16 string. /// A single byte character UTF-8 string. - std::string to_utf8string(const utf16string &value); + xsapi_internal_string to_utf8string(const xsapi_internal_wstring &value); /// /// Converts to a platform dependent Unicode string type. /// /// A single byte character UTF-8 string. /// A platform dependent string type. - string_t to_string_t(const std::string &s); + string_t to_string_t(const xsapi_internal_string_t &s); /// /// Encode the given byte array into a base64 string @@ -281,13 +279,13 @@ namespace services /// /// Decode the given base64 string to a byte array /// - std::vector from_base64(const string_t& str); + std::vector from_base64(const xsapi_internal_string& str); template - string_t print_string(const Source& val, const std::locale& loc) + xsapi_internal_string print_string(const Source& val, const std::locale& loc) { - ostringstream_t oss; - oss.imbue(loc); + xsapi_internal_ostringstream oss; + (void) oss.imbue(loc); oss << val; if (oss.bad()) { @@ -297,11 +295,11 @@ namespace services } template - Target scan_string(const string_t& str, const std::locale& loc) + Target scan_string(const xsapi_internal_string& str, const std::locale& loc) { Target t; - istringstream_t iss(str); - iss.imbue(loc); + xsapi_internal_istringstream iss(str); + (void) iss.imbue(loc); iss >> t; if (iss.bad()) { @@ -380,7 +378,7 @@ namespace services { struct uri_components { - uri_components() : m_path(_XPLATSTR("/")), m_port(-1) + uri_components() : m_path("/"), m_port(-1) {} uri_components(const uri_components& other) : @@ -433,14 +431,14 @@ namespace services return *this; } - string_t join(); + xsapi_internal_string join(); - string_t m_scheme; - string_t m_host; - string_t m_user_info; - string_t m_path; - string_t m_query; - string_t m_fragment; + xsapi_internal_string m_scheme; + xsapi_internal_string m_host; + xsapi_internal_string m_user_info; + xsapi_internal_string m_path; + xsapi_internal_string m_query; + xsapi_internal_string m_fragment; int m_port; }; @@ -452,7 +450,7 @@ namespace services /// /// This function accepts both uris ('http://msn.com') and uri relative-references ('path1/path2?query') /// - bool validate(const string_t& encoded_string); + bool validate(const xsapi_internal_string& encoded_string); /// /// Parses the uri, setting each provided string to the value of that component. Components @@ -461,7 +459,7 @@ namespace services /// /// This function accepts both uris ('http://msn.com') and uri relative-references ('path1/path2?query') /// - bool parse(const string_t& encoded_string, uri_components& components); + bool parse(const xsapi_internal_string& encoded_string, uri_components& components); /// /// Unreserved characters are those that are allowed in a URI but do not have a reserved purpose. They include: @@ -618,14 +616,14 @@ namespace services /// 'encoded' is expected to point to an encoded zero-terminated string containing a uri /// bool inner_parse( - const char_t* encoded, - const char_t** scheme_begin, const char_t** scheme_end, - const char_t** uinfo_begin, const char_t** uinfo_end, - const char_t** host_begin, const char_t** host_end, + const char* encoded, + const char** scheme_begin, const char** scheme_end, + const char** uinfo_begin, const char** uinfo_end, + const char** host_begin, const char** host_end, _Out_ int* port, - const char_t** path_begin, const char_t** path_end, - const char_t** query_begin, const char_t** query_end, - const char_t** fragment_begin, const char_t** fragment_end); + const char** path_begin, const char** path_end, + const char** query_begin, const char** query_end, + const char** fragment_begin, const char** fragment_end); } } @@ -636,7 +634,7 @@ namespace services { public: - uri_exception(std::string msg) : m_msg(std::move(msg)) {} + uri_exception(xsapi_internal_string msg) : m_msg(std::move(msg)) {} ~uri_exception() noexcept {} @@ -646,7 +644,7 @@ namespace services } private: - std::string m_msg; + xsapi_internal_string m_msg; }; /// @@ -705,7 +703,7 @@ namespace services /// /// The URI as a string. /// The encoded string. - static string_t encode_uri(const string_t& raw, uri::components::component = components::full_uri); + static xsapi_internal_string encode_uri(const xsapi_internal_string& raw, uri::components::component = components::full_uri); /// /// Encodes a string by converting all characters except for RFC 3986 unreserved characters to their @@ -713,40 +711,40 @@ namespace services /// /// The UTF-8 string data. /// The encoded string. - static string_t encode_data_string(const string_t& utf8data); + static xsapi_internal_string encode_data_string(const xsapi_internal_string& utf8data); /// /// Decodes an encoded string. /// /// The URI as a string. /// The decoded string. - static string_t decode(const string_t& encoded); + static xsapi_internal_string decode(const xsapi_internal_string& encoded); /// /// Splits a path into its hierarchical components. /// /// The path as a string - /// A std::vector<string_t> containing the segments in the path. - static std::vector split_path(const string_t& path); + /// A std::vector<xsapi_internal_string> containing the segments in the path. + static std::vector split_path(const xsapi_internal_string& path); /// /// Splits a query into its key-value components. /// /// The query string - /// A std::map<string_t, string_t> containing the key-value components of the query. - static std::map split_query(const string_t& query); + /// A std::map<xsapi_internal_string, xsapi_internal_string> containing the key-value components of the query. + static std::map split_query(const xsapi_internal_string& query); /// /// Validates a string as a URI. /// /// The URI string to be validated. /// true if the given string represents a valid URI, false otherwise. - static bool validate(const string_t& uri_string); + static bool validate(const xsapi_internal_string& uri_string); /// /// Creates an empty uri /// - uri() { m_uri = _XPLATSTR("/"); }; + uri() { m_uri = "/"; }; /// /// Creates a URI from the given URI components. @@ -759,14 +757,14 @@ namespace services /// does not contain a valid URI. Use uri::validate if processing user-input. /// /// A pointer to an encoded string to create the URI instance. - uri(const char_t* uri_string); + uri(const char* uri_string); /// /// Creates a URI from the given encoded string. This will throw an exception if the string /// does not contain a valid URI. Use uri::validate if processing user-input. /// /// An encoded URI string to create the URI instance. - uri(const string_t& uri_string); + uri(const xsapi_internal_string& uri_string); /// /// Copy constructor. @@ -814,19 +812,19 @@ namespace services /// Get the scheme component of the URI as an encoded string. /// /// The URI scheme as a string. - const string_t& scheme() const { return m_components.m_scheme; } + const xsapi_internal_string& scheme() const { return m_components.m_scheme; } /// /// Get the user information component of the URI as an encoded string. /// /// The URI user information as a string. - const string_t& user_info() const { return m_components.m_user_info; } + const xsapi_internal_string& user_info() const { return m_components.m_user_info; } /// /// Get the host component of the URI as an encoded string. /// /// The URI host as a string. - const string_t& host() const { return m_components.m_host; } + const xsapi_internal_string& host() const { return m_components.m_host; } /// /// Get the port component of the URI. Returns -1 if no port is specified. @@ -838,19 +836,19 @@ namespace services /// Get the path component of the URI as an encoded string. /// /// The URI path as a string. - const string_t& path() const { return m_components.m_path; } + const xsapi_internal_string& path() const { return m_components.m_path; } /// /// Get the query component of the URI as an encoded string. /// /// The URI query as a string. - const string_t& query() const { return m_components.m_query; } + const xsapi_internal_string& query() const { return m_components.m_query; } /// /// Get the fragment component of the URI as an encoded string. /// /// The URI fragment as a string. - const string_t& fragment() const { return m_components.m_fragment; } + const xsapi_internal_string& fragment() const { return m_components.m_fragment; } /// /// Creates a new uri object with the same authority portion as this one, omitting the resource and query portions. @@ -869,7 +867,7 @@ namespace services /// bool is_empty() const { - return this->m_uri.empty() || this->m_uri == _XPLATSTR("/"); + return this->m_uri.empty() || this->m_uri == "/"; } /// @@ -881,7 +879,7 @@ namespace services /// true if this URI references the local host, false otherwise. bool is_host_loopback() const { - return !is_empty() && ((host() == _XPLATSTR("localhost")) || (host().size() > 4 && host().substr(0, 4) == _XPLATSTR("127."))); + return !is_empty() && ((host() == "localhost") || (host().size() > 4 && host().substr(0, 4) == "127.")); } /// @@ -892,7 +890,7 @@ namespace services /// bool is_host_wildcard() const { - return !is_empty() && (this->host() == _XPLATSTR("*") || this->host() == _XPLATSTR("+")); + return !is_empty() && (this->host() == "*" || this->host() == "+"); } /// @@ -944,14 +942,14 @@ namespace services /// true if the path portion of this URI is empty, false otherwise. bool is_path_empty() const { - return path().empty() || path() == _XPLATSTR("/"); + return path().empty() || path() == "/"; } /// /// Returns the full (encoded) URI as a string. /// /// The full encoded URI string. - string_t to_string() const + xsapi_internal_string to_string() const { return m_uri; } @@ -972,9 +970,9 @@ namespace services friend class uri_builder; // Encodes all characters not in given set determined by given function. - static string_t encode_impl(const string_t& raw, const std::function& should_encode); + static xsapi_internal_string encode_impl(const xsapi_internal_string& raw, const std::function& should_encode); - string_t m_uri; + xsapi_internal_string m_uri; details::uri_components m_components; }; @@ -1000,19 +998,19 @@ namespace services /// Get the scheme component of the URI as an encoded string. /// /// The URI scheme as a string. - const string_t& scheme() const { return m_uri.m_scheme; } + const xsapi_internal_string& scheme() const { return m_uri.m_scheme; } /// /// Get the user information component of the URI as an encoded string. /// /// The URI user information as a string. - const string_t& user_info() const { return m_uri.m_user_info; } + const xsapi_internal_string& user_info() const { return m_uri.m_user_info; } /// /// Get the host component of the URI as an encoded string. /// /// The URI host as a string. - const string_t& host() const { return m_uri.m_host; } + const xsapi_internal_string& host() const { return m_uri.m_host; } /// /// Get the port component of the URI. Returns -1 if no port is specified. @@ -1024,26 +1022,26 @@ namespace services /// Get the path component of the URI as an encoded string. /// /// The URI path as a string. - const string_t& path() const { return m_uri.m_path; } + const xsapi_internal_string& path() const { return m_uri.m_path; } /// /// Get the query component of the URI as an encoded string. /// /// The URI query as a string. - const string_t& query() const { return m_uri.m_query; } + const xsapi_internal_string& query() const { return m_uri.m_query; } /// /// Get the fragment component of the URI as an encoded string. /// /// The URI fragment as a string. - const string_t& fragment() const { return m_uri.m_fragment; } + const xsapi_internal_string& fragment() const { return m_uri.m_fragment; } /// /// Set the scheme of the URI. /// /// Uri scheme. /// A reference to this uri_builder to support chaining. - uri_builder& set_scheme(const string_t& scheme) + uri_builder& set_scheme(const xsapi_internal_string& scheme) { m_uri.m_scheme = scheme; return *this; @@ -1055,7 +1053,7 @@ namespace services /// User info as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& set_user_info(const string_t& user_info, bool do_encoding = false) + uri_builder& set_user_info(const xsapi_internal_string& user_info, bool do_encoding = false) { m_uri.m_user_info = do_encoding ? uri::encode_uri(user_info, uri::components::user_info) : user_info; return *this; @@ -1067,7 +1065,7 @@ namespace services /// Host as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& set_host(const string_t& host, bool do_encoding = false) + uri_builder& set_host(const xsapi_internal_string& host, bool do_encoding = false) { m_uri.m_host = do_encoding ? uri::encode_uri(host, uri::components::host) : host; return *this; @@ -1090,9 +1088,9 @@ namespace services /// Port as a string. /// A reference to this uri_builder to support chaining. /// When string can't be converted to an integer the port is left unchanged. - uri_builder& set_port(const string_t& port) + uri_builder& set_port(const xsapi_internal_string& port) { - istringstream_t portStream(port); + xsapi_internal_istringstream portStream(port); int port_tmp; portStream >> port_tmp; if (portStream.fail() || portStream.bad()) @@ -1109,7 +1107,7 @@ namespace services /// Path as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& set_path(const string_t& path, bool do_encoding = false) + uri_builder& set_path(const xsapi_internal_string& path, bool do_encoding = false) { m_uri.m_path = do_encoding ? uri::encode_uri(path, uri::components::path) : path; return *this; @@ -1122,7 +1120,7 @@ namespace services /// Query as a decoded string. /// Specify whether apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& set_query(const string_t& query, bool do_encoding = false) + uri_builder& set_query(const xsapi_internal_string& query, bool do_encoding = false) { m_uri.m_query = do_encoding ? uri::encode_uri(query, uri::components::query) : query; return *this; @@ -1134,7 +1132,7 @@ namespace services /// Fragment as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& set_fragment(const string_t& fragment, bool do_encoding = false) + uri_builder& set_fragment(const xsapi_internal_string& fragment, bool do_encoding = false) { m_uri.m_fragment = do_encoding ? uri::encode_uri(fragment, uri::components::fragment) : fragment; return *this; @@ -1154,7 +1152,7 @@ namespace services /// Path to append as a already encoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& append_path(const string_t& path, bool do_encoding = false); + uri_builder& append_path(const xsapi_internal_string& path, bool do_encoding = false); /// /// Appends another query to the query of this uri_builder. @@ -1162,7 +1160,7 @@ namespace services /// Query to append as a decoded string. /// Specify whether to apply URI encoding to the given string. /// A reference to this uri_builder to support chaining. - uri_builder& append_query(const string_t& query, bool do_encoding = false); + uri_builder& append_query(const xsapi_internal_string& query, bool do_encoding = false); /// /// Appends an relative uri (Path, Query and fragment) at the end of the current uri. @@ -1179,7 +1177,7 @@ namespace services /// The value portion of the query string /// A reference to this uri_builder to support chaining. template - uri_builder& append_query(const string_t& name, const T& value, bool do_encoding = true) + uri_builder& append_query(const xsapi_internal_string& name, const T& value, bool do_encoding = true) { auto encodedName = name; auto encodedValue = ::xbox::services::convert::print_string(value, std::locale::classic()); @@ -1207,7 +1205,7 @@ namespace services } auto encodedQuery = encodedName; - encodedQuery.append(_XPLATSTR("=")); + encodedQuery.append("="); encodedQuery.append(encodedValue); // The query key value pair was already encoded by us or the user separately. return append_query(encodedQuery, false); @@ -1217,7 +1215,7 @@ namespace services /// Combine and validate the URI components into a encoded string. An exception will be thrown if the URI is invalid. /// /// The created URI as a string. - string_t to_string(); + xsapi_internal_string to_string(); /// /// Combine and validate the URI components into a URI class instance. An exception will be thrown if the URI is invalid. diff --git a/Source/Shared/internal_mem.cpp b/Source/Shared/internal_mem.cpp index 6616e16e..d4189104 100644 --- a/Source/Shared/internal_mem.cpp +++ b/Source/Shared/internal_mem.cpp @@ -58,7 +58,10 @@ void STDAPIVCALLTYPE Free( assert(g_pMemFreeHook); try { + DISABLE_WARNING_PUSH; + SUPPRESS_WARNING_UNINITIALIZED_MEMORY; g_pMemFreeHook(pointer, memoryType); + DISABLE_WARNING_POP; } catch (...) { @@ -98,4 +101,4 @@ char* Make(const string_t& strt) return cstr; } -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/internal_mem.h b/Source/Shared/internal_mem.h index 409d3461..80147e8d 100644 --- a/Source/Shared/internal_mem.h +++ b/Source/Shared/internal_mem.h @@ -113,6 +113,16 @@ using BasicStringsteam = std::basic_stringstream>; using Stringstream = BasicStringsteam; using WStringstream = BasicStringsteam; +template> +using BasicIStringsteam = std::basic_istringstream>; +using IStringstream = BasicIStringsteam; +using WIStringstream = BasicIStringsteam; + +template> +using BasicOStringsteam = std::basic_ostringstream>; +using OStringstream = BasicOStringsteam; +using WOStringstream = BasicOStringsteam; + template using Deque = std::deque>; @@ -226,7 +236,7 @@ inline void DeleteArray(T* arrayPtr, size_t elementCount) { arrayPtr[i].~T(); } - Free(arrayPtr); + Free(arrayPtr, 0); } inline char** MakeArray(const Vector& vector) @@ -283,6 +293,25 @@ using xsapi_internal_wstring = xbox::services::WString; using xsapi_internal_stringstream = xbox::services::Stringstream; using xsapi_internal_wstringstream = xbox::services::WStringstream; +using xsapi_internal_istringstream = xbox::services::IStringstream; +using xsapi_internal_wistringstream = xbox::services::WIStringstream; + +using xsapi_internal_ostringstream = xbox::services::OStringstream; +using xsapi_internal_wostringstream = xbox::services::WOStringstream; + +#ifdef _WIN32 +using xsapi_internal_string_t = xbox::services::WString; +using xsapi_internal_stringstream_t = xbox::services::WStringstream; +using xsapi_internal_istringstream_t = xbox::services::WIStringstream; +using xsapi_internal_ostringstream_t = xbox::services::WOStringstream; +#else +using xsapi_internal_string_t = xbox::services::String; +using xsapi_internal_stringstream_t = xbox::services::Stringstream; +using xsapi_internal_istringstream_t = xbox::services::IStringstream; +using xsapi_internal_ostringstream_t = xbox::services::OStringstream; +#endif + + template using xsapi_internal_dequeue = xbox::services::Deque; diff --git a/Source/Shared/local_config.cpp b/Source/Shared/local_config.cpp index 639c5c31..d0681684 100644 --- a/Source/Shared/local_config.cpp +++ b/Source/Shared/local_config.cpp @@ -4,7 +4,6 @@ #include "pch.h" #include #include "local_config.h" -#include "xbox_system_factory.h" #include "xsapi_utils.h" using namespace std; diff --git a/Source/Shared/public_utils_legacy.cpp b/Source/Shared/public_utils_legacy.cpp index f1a5441e..0723dc35 100644 --- a/Source/Shared/public_utils_legacy.cpp +++ b/Source/Shared/public_utils_legacy.cpp @@ -1,14 +1,13 @@ #include "pch.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/writer.h" - #define MS_TICKS (10000) #define SECOND_TICKS (1000 * MS_TICKS) #define MINUTE_TICKS (60 * SECOND_TICKS) #define HOUR_TICKS (60 * MINUTE_TICKS) #define DAY_TICKS (24 * HOUR_TICKS) +using namespace xbox::services::cppresturi::utility; + NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN xbl_error_code ConvertHrToXblErrorCode(HRESULT hr) @@ -278,22 +277,6 @@ namespace legacy #endif } - web::json::value ParseJson(const char* jsonString) - { - try - { - if (jsonString) - { - return web::json::value::parse(StringTFromUtf8(jsonString)); - } - } - catch (web::json::json_exception) - { - } - - return web::json::value::null(); - } - std::string SerializeJson(const rapidjson::Value& json) { rapidjson::StringBuffer buffer; @@ -303,18 +286,6 @@ namespace legacy return buffer.GetString(); } - rapidjson::Document RapidJsonFromWebJson(_In_ const web::json::value& json) - { - rapidjson::Document doc; - doc.Parse(StringFromStringT(json.serialize()).c_str()); - return doc; - } - - web::json::value WebJsonFromRapidJson(_In_ const rapidjson::Value& json) - { - return web::json::value::parse(StringTFromUtf8(SerializeJson(json).c_str())); - } - const rapidjson::Value& ExtractJsonField( _In_ const rapidjson::Value& json, _In_ const std::string& name, @@ -338,21 +309,6 @@ namespace legacy return json; } - std::string ExtractJsonString( - _In_ const rapidjson::Value& jsonValue, - _In_ const std::string& stringName, - _In_ bool required, - _In_ const std::string& defaultValue - ) - { - const rapidjson::Value& field(ExtractJsonField(jsonValue, stringName, required)); - if ((!field.IsString() && !required) || field.IsNull()) - { - return defaultValue; - } - return field.GetString(); - } - uint64_t ExtractJsonUint64( _In_ const rapidjson::Value& jsonValue, _In_ const std::string& name, @@ -383,15 +339,15 @@ namespace legacy return Transform(stringArray, arrayCount, StringTFromUtf8); } - utility::datetime DatetimeFromTimeT(time_t time) + xbox::services::cppresturi::utility::datetime DatetimeFromTimeT(time_t time) { const uint64_t epoch_offset = 11644473600LL; uint64_t result = epoch_offset + time; result *= SECOND_TICKS; // convert to 10e-7 - return utility::datetime() + result; + return xbox::services::cppresturi::utility::datetime() + result; } - time_t TimeTFromDatetime(const utility::datetime& datetime) + time_t TimeTFromDatetime(const xbox::services::cppresturi::utility::datetime& datetime) { const uint64_t epoch_offset = 11644473600LL; uint64_t seconds = datetime.to_interval() / SECOND_TICKS; diff --git a/Source/Shared/public_utils_legacy.h b/Source/Shared/public_utils_legacy.h index 3a68be55..b69699c7 100644 --- a/Source/Shared/public_utils_legacy.h +++ b/Source/Shared/public_utils_legacy.h @@ -3,6 +3,10 @@ #pragma once +#include "HookedUri/uri.h" +#include "HookedUri/uri_builder.h" +#include "HookedUri/asyncrt_utils.h" + #ifndef MAKE_HTTP_HRESULT #define MAKE_HTTP_HRESULT(code) MAKE_HRESULT(1, 0x019, code) #endif @@ -13,9 +17,6 @@ xbl_error_code ConvertHrToXblErrorCode(HRESULT hr); namespace legacy { - int CharTFromUft8( const char*, char_t*, int ); - int Utf8FromCharT( const char_t*, char*, int ); - string_t StringTFromUtf8( _In_z_ const char* utf8 ); std::string StringFromStringT(_In_ const string_t& stringt); @@ -42,28 +43,14 @@ namespace legacy int Stricmp(const string_t& left, const string_t& right); - web::json::value ParseJson(const char* jsonString); - std::string SerializeJson(const rapidjson::Value& json); - rapidjson::Document RapidJsonFromWebJson(_In_ const web::json::value& json); - - web::json::value WebJsonFromRapidJson(_In_ const rapidjson::Value& json); - const rapidjson::Value& ExtractJsonField( _In_ const rapidjson::Value& json, _In_ const std::string& name, _In_ bool required ); - std::string ExtractJsonString( - _In_ const rapidjson::Value& jsonValue, - _In_ const std::string& stringName, - _In_ bool required = false, - _In_ const std::string& defaultValue = std::string() - ); - - uint64_t ExtractJsonUint64( _In_ const rapidjson::Value& jsonValue, _In_ const std::string& name, @@ -106,9 +93,9 @@ namespace legacy std::vector StringTVectorFromCStringArray(const char** stringArray, size_t arrayCount); - utility::datetime DatetimeFromTimeT(time_t time); + xbox::services::cppresturi::utility::datetime DatetimeFromTimeT(time_t time); - time_t TimeTFromDatetime(const utility::datetime& datetime); + time_t TimeTFromDatetime(const xbox::services::cppresturi::utility::datetime& datetime); char_t ToLower(char_t c); @@ -218,4 +205,4 @@ namespace legacy #endif } -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file +NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/service_call_logger.cpp b/Source/Shared/service_call_logger.cpp deleted file mode 100644 index 7532d4e4..00000000 --- a/Source/Shared/service_call_logger.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" - -#include "service_call_logger.h" -#include "service_call_logger_data.h" - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -std::shared_ptr service_call_logger::get_singleton_instance() -{ - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - if (xsapiSingleton) - { - std::lock_guard guard(xsapiSingleton->m_singletonLock); - if (xsapiSingleton->m_serviceLoggerSingleton == nullptr) - { - xsapiSingleton->m_serviceLoggerSingleton = std::shared_ptr(new service_call_logger()); - } - return xsapiSingleton->m_serviceLoggerSingleton; - } - return nullptr; -} - -service_call_logger::service_call_logger() : - m_isEnabled(false), - m_firstWrite(false) -{ -} - -service_call_logger::~service_call_logger() -{ - disable(); -} - -void service_call_logger::enable() -{ - if (m_isEnabled) - { - return; - } -#if HC_PLATFORM_IS_MICROSOFT - create_log_file(); -#endif - m_isEnabled = true; - m_firstWrite = true; -} - -void service_call_logger::disable() -{ - std::lock_guard lock(m_writeLock); - if (!m_isEnabled) - { - return; - } - m_isEnabled = false; - if(m_fileStream.is_open()) - { - m_fileLocation = ""; - m_fileStream.close(); - } -} - -bool service_call_logger::is_enabled() -{ - return m_isEnabled; -} - -void service_call_logger::log(_In_ const xsapi_internal_string& item) -{ - if (m_isEnabled) - { - std::lock_guard lock(m_writeLock); - if (m_firstWrite) - { - add_data_to_file(service_call_logger_data::get_csv_header()); - m_firstWrite = false; - } - add_data_to_file(item); - } -} - -xsapi_internal_string service_call_logger::file_location() -{ - return m_fileLocation; -} -#if HC_PLATFORM_IS_MICROSOFT -void service_call_logger::create_log_file() -{ - // - // Write to title scratch folder - - SYSTEMTIME stLocalTime; - GetLocalTime(&stLocalTime); - wchar_t fileLocation[MAX_PATH]; - -#if HC_PLATFORM == HC_PLATFORM_XDK - swprintf_s(fileLocation, _T("d:\\%s-%04d%02d%02d-%02d%02d%02d.csv"), - _T("callHistoryJson"), - stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, - stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); -#elif HC_PLATFORM == HC_PLATFORM_UWP - Windows::Storage::ApplicationData^ currentAppData = Windows::Storage::ApplicationData::Current; - const xsapi_internal_wstring fileDir = currentAppData->TemporaryFolder->Path->Data(); - - swprintf_s(fileLocation, _T("%s\\%s-%04d%02d%02d-%02d%02d%02d.csv"), - fileDir.c_str(), - _T("callHistoryJson"), - stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, - stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); -#else - swprintf_s(fileLocation, _T("%s-%04d%02d%02d-%02d%02d%02d.csv"), - _T("callHistoryJson"), - stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, - stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); -#endif - - m_fileLocation = utils::internal_string_from_string_t(fileLocation); - - m_fileStream.open(m_fileLocation.data(), std::ios_base::app | std::ios_base::out); - - if (!m_fileStream.is_open()) - { - LOGS_ERROR <<"WriteFile failed. Path: " << m_fileLocation; - return; - } -} -#endif -void service_call_logger::add_data_to_file(_In_ const xsapi_internal_string& data) -{ - if (m_fileStream.is_open()) - { - m_fileStream << data.c_str(); - m_fileStream.flush(); - } - else - { - LOGS_ERROR << "WriteFile failed.Path '" << m_fileLocation << "'; Contents: '" << data << "'"; - } -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/service_call_logger.h b/Source/Shared/service_call_logger.h deleted file mode 100644 index 84530140..00000000 --- a/Source/Shared/service_call_logger.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - - -#pragma once - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -class service_call_logger -{ -public: - - /// - /// Gets the service_call_logger singleton instance - /// - static std::shared_ptr get_singleton_instance(); - - /// - /// Enables the tracking of service calls - /// - void enable(); - - /// - /// Disables the tracking of service calls - /// - void disable(); - - /// - /// Returns whether or not the loggger will accept log calls - /// - bool is_enabled(); - - ~service_call_logger(); - - void log(_In_ const xsapi_internal_string& item); - - xsapi_internal_string file_location(); - -private: - -#if HC_PLATFORM_IS_MICROSOFT - void create_log_file(); -#endif - void add_data_to_file(_In_ const xsapi_internal_string& data); - - service_call_logger(); - service_call_logger(const service_call_logger&); - void operator=(const service_call_logger&); - - std::ofstream m_fileStream; - xsapi_internal_string m_fileLocation; - bool m_isEnabled; - bool m_firstWrite; - - std::mutex m_writeLock; - -}; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/service_call_logger_data.cpp b/Source/Shared/service_call_logger_data.cpp deleted file mode 100644 index 658a5468..00000000 --- a/Source/Shared/service_call_logger_data.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" - -#include "service_call_logger_data.h" - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -// -// service_call_logger_data - -service_call_logger_data::service_call_logger_data( - _In_ xsapi_internal_string host, - _In_ xsapi_internal_string uri, - _In_ uint64_t xuid, - _In_ bool isGet, - _In_ uint32_t httpStatusCode, - _In_ xsapi_internal_string requestHeader, - _In_ xsapi_internal_string requestBody, - _In_ xsapi_internal_string responseHeader, - _In_ xsapi_internal_string responseBody, - _In_ std::chrono::milliseconds elapsedCallTime, - _In_ chrono_clock_t::time_point requestTime, - _In_ xsapi_internal_string method - ) : - m_host(std::move(host)), - m_uri(std::move(uri)), - m_xuid(xuid), - m_isGet(std::move(isGet)), - m_requestHeader(std::move(requestHeader)), - m_requestBody(std::move(requestBody)), - m_responseHeader(std::move(responseHeader)), - m_responseBody(std::move(responseBody)), - m_httpStatusCode(std::move(httpStatusCode)), - m_elapsedCallTime(std::move(elapsedCallTime)), - m_requestTime(std::move(requestTime)), - m_isShoulderTap(false), - m_isInGameEvent(false), - m_changeNumber(0), - m_version(0), - m_method(std::move(method)) -{ - init(); -} - -service_call_logger_data::service_call_logger_data( - _In_ uint64_t xuid, - _In_ xsapi_internal_string eventName, - _In_ xsapi_internal_string eventPlayerSessionId, - _In_ xsapi_internal_string eventDimensions, - _In_ xsapi_internal_string eventMeasurements, - _In_ chrono_clock_t::time_point requestTime - ) : - m_xuid(xuid), - m_host("inGameEvents"), - m_uri("inGameEvents"), - m_requestTime(std::move(requestTime)), - m_eventName(std::move(eventName)), - m_playerSessionId(std::move(eventPlayerSessionId)), - m_dimensions(std::move(eventDimensions)), - m_measurements(std::move(eventMeasurements)), - m_elapsedCallTime(0), - m_httpStatusCode(0), - m_isGet(false), - m_isShoulderTap(false), - m_isInGameEvent(true), - m_changeNumber(0), - m_version(0) -{ - init(); -} - -void service_call_logger_data::init() -{ - auto singleton = get_xsapi_singleton(); - if (singleton) - { - m_id = ++singleton->m_loggerId; - } - else - { - m_id = 0; - } - m_breadCrumb = utils::create_guid(true); -} - -xsapi_internal_string service_call_logger_data::to_string() const -{ - xsapi_internal_stringstream result; - - //Writing properties to string in a csv format. Order matters. - - //host - result << '\"'; - result << m_host; - result << "\","; - - //uri - result << '\"'; - result << m_uri; - result << "\","; - - //xboxUserId - result << '\"'; - result << m_xuid; - result << "\","; - - //multiplayer correlation id - result << '\"'; - result << m_multiplayerCorrelationId; - result << "\","; - - //requestHeader - result << '\"'; - result << utils::escape_special_characters(m_requestHeader); - result << "\","; - - //requestBody - result << '\"'; - result << utils::escape_special_characters(m_requestBody); - result << "\","; - - //responseHeader - result << '\"'; - result << utils::escape_special_characters(m_responseHeader); - result << "\","; - - //responseBody - result << '\"'; - result << utils::escape_special_characters(m_responseBody); - result << "\","; - - //httpStatusCode - result << '\"'; - result << m_httpStatusCode; - result << "\","; - - //ellapsedCalltime - result << '\"'; - result << m_elapsedCallTime.count(); - result << "\","; - - //requestTime - result << '\"'; - result << utils::convert_timepoint_to_string(m_requestTime); - result << "\","; - - //isGet - result << '\"'; - result << ((m_isGet) ? "true": "false"); - result << "\","; - - //id - result << '\"'; - result << m_id; - result << "\","; - - //isShoulderTap - result << '\"'; - result << ((m_isShoulderTap) ? "true" : "false"); - result << "\","; - - //changeNumber - result << '\"'; - result << m_changeNumber; - result << "\","; - - //sessionReferenceUriPath - result << '\"'; - result << m_sessionReferenceUriPath; - result << "\","; - - //isInGameEvent - result << '\"'; - result << ((m_isInGameEvent) ? "true" : "false"); - result << "\","; - - //eventName - result << '\"'; - result << m_eventName; - result << "\","; - - //playerSessionId - result << '\"'; - result << m_playerSessionId; - result << "\","; - - //version - result << '\"'; - result << m_version; - result << "\","; - - //dimensions - result << '\"'; - result << utils::escape_special_characters(m_dimensions); - result << "\","; - - //measurements - result << '\"'; - result << utils::escape_special_characters(m_measurements); - result << "\","; - - //breadCrumb - result << '\"'; - result << m_breadCrumb; - result << "\","; - - //breadCrumb - result << '\"'; - result << m_method; - result << "\""; - - result << "\n"; - - return result.str(); -} - -xsapi_internal_string service_call_logger_data::get_csv_header() -{ - xsapi_internal_stringstream result; - - //headers - result << "v1510\n"; - - result << "\"Host\","; - - result << "\"Uri\","; - - result << "\"XboxUserId\","; - - result << "\"MultiplayerCorrelationId\","; - - result << "\"RequestHeaders\","; - - result << "\"RequestBody\","; - - result << "\"ResponseHeaders\","; - - result << "\"ResponseBody\","; - - result << "\"HttpStatusCode\","; - - result << "\"EllapsedCallTimeMs\","; - - result << "\"ReqTimeUTC\","; - - result << "\"IsGet\","; - - result << "\"LoggerId\","; - - result << "\"IsShoulderTap\","; - - result << "\"ChangeNumber\","; - - result << "\"SessionReferenceUriPath\","; - - result << "\"IsInGameEvent\","; - - result << "\"EventName\","; - - result << "\"EventPlayerSessionId\","; - - result << "\"EventVersion\","; - - result << "\"EventDimensionData\","; - - result << "\"EventMeasurementData\","; - - result << "\"BreadCrumb\","; - - result << "\"Method\""; - - result << "\n"; - - return result.str(); -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/service_call_logger_data.h b/Source/Shared/service_call_logger_data.h deleted file mode 100644 index 96298f20..00000000 --- a/Source/Shared/service_call_logger_data.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - - -#pragma once - -#include "cpprest/json.h" - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -class service_call_logger_data -{ -public: - - service_call_logger_data( - _In_ xsapi_internal_string host, - _In_ xsapi_internal_string uri, - _In_ uint64_t xuid, - _In_ bool isGet, - _In_ uint32_t httpStatusCode, - _In_ xsapi_internal_string requestHeader, - _In_ xsapi_internal_string requestBody, - _In_ xsapi_internal_string responseHeader, - _In_ xsapi_internal_string responseBody, - _In_ std::chrono::milliseconds elapsedCallTime, - _In_ chrono_clock_t::time_point requestTime, - _In_ xsapi_internal_string method - ); - - service_call_logger_data( - _In_ uint64_t xuid, - _In_ xsapi_internal_string eventName, - _In_ xsapi_internal_string eventPlayerSessionId, - _In_ xsapi_internal_string eventDimensions, - _In_ xsapi_internal_string eventMeasurements, - _In_ chrono_clock_t::time_point requestTime - ); - - /// - /// Output as multi-line string - /// - xsapi_internal_string to_string() const; - - static xsapi_internal_string get_csv_header(); - -private: - - void init(); - - xsapi_internal_string m_host; - xsapi_internal_string m_uri; - - uint64_t m_xuid; - - xsapi_internal_string m_multiplayerCorrelationId; - - xsapi_internal_string m_requestHeader; - xsapi_internal_string m_requestBody; - - xsapi_internal_string m_responseHeader; - xsapi_internal_string m_responseBody; - - uint32_t m_httpStatusCode; - - std::chrono::milliseconds m_elapsedCallTime; - chrono_clock_t::time_point m_requestTime; - - bool m_isGet; - uint32_t m_id; - - bool m_isShoulderTap; - uint64_t m_changeNumber; - xsapi_internal_string m_sessionReferenceUriPath; - - bool m_isInGameEvent; - xsapi_internal_string m_eventName; - xsapi_internal_string m_playerSessionId; - uint16_t m_version; - xsapi_internal_string m_dimensions; - xsapi_internal_string m_measurements; - xsapi_internal_string m_method; - - xsapi_internal_string m_breadCrumb; - - static const uint32_t s_invalidId = (uint32_t)-1; -}; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/service_call_logger_protocol.cpp b/Source/Shared/service_call_logger_protocol.cpp deleted file mode 100644 index b378c9d3..00000000 --- a/Source/Shared/service_call_logger_protocol.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" - -#include "service_call_logger_protocol.h" -#include "service_call_logger.h" -#include "service_call_logger_data.h" - -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK -#include - -using namespace pplx; -using namespace Platform; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Core; -using namespace Windows::ApplicationModel::Activation; -using namespace Windows::Foundation; -#endif - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -std::shared_ptr service_call_logger_protocol::get_singleton_instance() -{ - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - std::lock_guard guard(xsapiSingleton->m_serviceLoggerProtocolSingletonLock); - if (xsapiSingleton->m_serviceLoggerProtocolSingleton == nullptr) - { - xsapiSingleton->m_serviceLoggerProtocolSingleton = std::shared_ptr(new service_call_logger_protocol()); - } - return xsapiSingleton->m_serviceLoggerProtocolSingleton; -} - -service_call_logger_protocol::service_call_logger_protocol() -{ -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK - m_onActivatedToken.Value = 0; -#endif -} - -void service_call_logger_protocol::register_for_protocol_activation() -{ -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK - if (m_onActivatedToken.Value != 0) - { - return; - } - try - { - if (CoreApplication::GetCurrentView() == nullptr) - { - return; - } - } - catch(Platform::Exception^ ex) - { - LOG_ERROR("Exception on CoreApplication::GetCurrentView()!"); - return; - } - - std::weak_ptr thisWeakPtr = shared_from_this(); - TypedEventHandler^ activatedEvent = ref new TypedEventHandler( - [thisWeakPtr](CoreApplicationView^ applicationView, IActivatedEventArgs^ args) - { - std::shared_ptr pThis(thisWeakPtr.lock()); - // Only handling protocol activation here - - if (pThis == nullptr || args->Kind != Activation::ActivationKind::Protocol) - { - return; - } - - IProtocolActivatedEventArgs^ protocolArgs = dynamic_cast< IProtocolActivatedEventArgs^>(args); - Windows::Foundation::Uri^ url = ref new Windows::Foundation::Uri(protocolArgs->Uri->RawUri); - - if (utils::str_icmp(url->Host->Data(), _T("serviceCallTracking")) == 0) - { - pThis->process_service_call_tracking_activation_uri(url); - } - }); - - try - { - m_onActivatedToken = CoreApplication::GetCurrentView()->Activated += activatedEvent; - } - catch (Platform::Exception^ ex) - { - std::string exMsg("Exception on CoreApplication::GetCurrentView()->Activated"); - exMsg += xbox::services::convert::to_utf8string(ex->Message->Data()); - LOG_ERROR(exMsg); - return; - } -#endif -} - -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK -void service_call_logger_protocol::process_service_call_tracking_activation_uri(_In_ Windows::Foundation::Uri^ activationUri) -{ - auto serviceCallLogger{ service_call_logger::get_singleton_instance() }; - if (serviceCallLogger) - { - WwwFormUrlDecoder^ decoder = activationUri->QueryParsed; - if (decoder->Size == 0) - { - return; - } - - // Check activationUri for relevant query arguments - for (auto entry : decoder) - { - if ((utils::str_icmp(entry->Name->Data(), _T("state")) == 0)) - { - if (utils::str_icmp(entry->Value->Data(), _T("start")) == 0) - { - serviceCallLogger->enable(); - set_state_bread_crumb(true); - } - else if (utils::str_icmp(entry->Value->Data(), _T("stop")) == 0) - { - serviceCallLogger->disable(); - set_state_bread_crumb(false); - } - } - } - } - else - { - LOGS_WARN << "Got service call logger protocol activiation but XSAPI was not initializated."; - } -} -#endif - -void service_call_logger_protocol::set_state_bread_crumb(_In_ bool isTracking) -{ - // IMPORTANT: xbTrace app depends on this filename, so please talk to xbTrace owner before - // considering any changes to this name -#if HC_PLATFORM == HC_PLATFORM_XDK || XSAPI_UNIT_TESTS - string_t filePath = _T("d:\\callHistoryJson.tmp"); -#else - Windows::Storage::ApplicationData^ currentAppData = Windows::Storage::ApplicationData::Current; - const string_t fileDir = currentAppData->TemporaryFolder->Path->Data(); - wchar_t filePathTemp[MAX_PATH]; - swprintf_s(filePathTemp, _T("%s\\callHistoryJson.tmp"), fileDir.c_str()); - string_t filePath = filePathTemp; -#endif - - // Try delete the old file no matter what. So the new created file will have latest timestamp. - DeleteFile(filePath.c_str()); - - if (isTracking) - { - std::ofstream file; - file.open(filePath, std::ios_base::app | std::ios_base::out); - - if (!file.is_open()) - { - LOGS_ERROR << "WriteFile failed: " < -{ -public: - - /// - /// Gets the service_call_logger singleton instance - /// - static std::shared_ptr get_singleton_instance(); - - /// - /// Enables Logs to be enabled/disabled through protocol activation - /// - void register_for_protocol_activation(); - -private: -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK - void process_service_call_tracking_activation_uri(_In_ Windows::Foundation::Uri^ activationUri); - Windows::Foundation::EventRegistrationToken m_onActivatedToken; -#endif - void set_state_bread_crumb(_In_ bool isTracking); - - service_call_logger_protocol(); - service_call_logger_protocol(const service_call_logger_protocol&); - void operator=(const service_call_logger_protocol&); -}; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/service_call_logging_config.cpp b/Source/Shared/service_call_logging_config.cpp deleted file mode 100644 index 20d4cfb0..00000000 --- a/Source/Shared/service_call_logging_config.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" - -#include "service_call_logging_config.h" -#include "service_call_logger.h" -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK || XSAPI_UNIT_TESTS -#include "service_call_logger_protocol.h" -#endif - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -#if HC_PLATFORM_IS_MICROSOFT - -std::shared_ptr service_call_logging_config::get_singleton_instance() -{ - auto xsapiSingleton = get_xsapi_singleton(); - if (xsapiSingleton) - { - if (xsapiSingleton->m_serviceLoggingConfigSingleton == nullptr) - { - std::lock_guard guard(xsapiSingleton->m_singletonLock); - if (xsapiSingleton->m_serviceLoggingConfigSingleton == nullptr) - { - xsapiSingleton->m_serviceLoggingConfigSingleton = std::shared_ptr(new service_call_logging_config()); - } - } - return xsapiSingleton->m_serviceLoggingConfigSingleton; - } - else - { - LOGS_DEBUG << "Service Call logging can't be configured until XSAPI is initialized."; - return nullptr; - } -} - -service_call_logging_config::service_call_logging_config() -{ -} - -void service_call_logging_config::enable() -{ - service_call_logger::get_singleton_instance()->enable(); -} - -void service_call_logging_config::disable() -{ - service_call_logger::get_singleton_instance()->disable(); -} - -#if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK || XSAPI_UNIT_TESTS -void service_call_logging_config::_Register_for_protocol_activation() -{ - service_call_logger_protocol::get_singleton_instance()->register_for_protocol_activation(); -} -#endif - -#endif // HC_PLATFORM_IS_MICROSOFT - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/service_call_logging_config.h b/Source/Shared/service_call_logging_config.h deleted file mode 100644 index 72a92f75..00000000 --- a/Source/Shared/service_call_logging_config.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma once - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -#if HC_PLATFORM_IS_MICROSOFT - -class service_call_logging_config -{ -public: - - /// - /// Gets the service_call_logger singleton instance - /// - static std::shared_ptr get_singleton_instance(); - - /// - /// Enables the tracking of service calls - /// - void enable(); - - /// - /// Disables the tracking of service calls - /// - void disable(); - -#if HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_UWP || XSAPI_UNIT_TESTS - /// - /// Internal API - /// Enables Logs to be enabled/disabled through protocol activation - /// - void _Register_for_protocol_activation(); -#endif - -private: - service_call_logging_config(); - service_call_logging_config(const service_call_logging_config&); - void operator=(const service_call_logging_config&); - friend struct ::XblContext; -}; -#endif // HC_PLATFORM_IS_MICROSOFT - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/service_call_routed_handler.cpp b/Source/Shared/service_call_routed_handler.cpp index ca8d4e70..ca5ed5c9 100644 --- a/Source/Shared/service_call_routed_handler.cpp +++ b/Source/Shared/service_call_routed_handler.cpp @@ -25,7 +25,7 @@ ServiceCallRoutedHandler::~ServiceCallRoutedHandler() noexcept void ServiceCallRoutedHandler::HCCallRoutedHandler( _In_ HCCallHandle call, - _In_opt_ void* context + _In_ void* context ) { auto pThis{ static_cast(context) }; diff --git a/Source/Shared/service_call_routed_handler.h b/Source/Shared/service_call_routed_handler.h index f5bbc0fd..f3e694fe 100644 --- a/Source/Shared/service_call_routed_handler.h +++ b/Source/Shared/service_call_routed_handler.h @@ -20,7 +20,7 @@ public: private: static void HCCallRoutedHandler( _In_ HCCallHandle call, - _In_opt_ void* context + _In_ void* context ); String GetFormattedResponse( diff --git a/Source/Shared/shared_macros.h b/Source/Shared/shared_macros.h index 5070743c..f2d0939d 100644 --- a/Source/Shared/shared_macros.h +++ b/Source/Shared/shared_macros.h @@ -163,12 +163,6 @@ return m_internalObj->methodName(); \ } -#define DEFINE_GET_STRING_VECTOR(className, methodName) \ - std::vector className::methodName() const \ - { \ - return utils::std_string_vector_from_internal_string_vector(m_internalObj->methodName()); \ - } - #define DEFINE_GET_ENUM_TYPE(className, enumType, methodName) \ enumType className::methodName() const \ { \ @@ -205,3 +199,66 @@ return m_internalObj->methodName(); \ } + +// Disable Warning macros + +// if msvc +#if defined (_MSC_VER) + +#define DISABLE_WARNING_PUSH __pragma(warning(push)) +#define DISABLE_WARNING_POP __pragma(warning(pop)) +#define DISABLE_WARNING(warningCode) __pragma(warning(disable:warningCode)) // expects numeric code for msvc +#define SUPPRESS_ANALYSIS_WARNING(warningCode) __pragma(warning(suppress:warningCode)) + +#define SUPPRESS_WARNING_NULL_PTR_DEREFERENCE SUPPRESS_ANALYSIS_WARNING(6011) +#define SUPPRESS_WARNING_UNINITIALIZED_MEMORY SUPPRESS_ANALYSIS_WARNING(6001) +#define SUPPRESS_WARNING_EXPRESSION_NOT_TRUE SUPPRESS_ANALYSIS_WARNING(28020) +#define SUPPRESS_WARNING_UNINITIALIZED_MEMBER SUPPRESS_ANALYSIS_WARNING(26495) +#define SUPPRESS_WARNING_UNNAMED_CUSTOM_OBJ SUPPRESS_ANALYSIS_WARNING(26444) + + +#elif defined(__GNUC__) + +#define DO_PRAGMA(X) _Pragma(#X) +#define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push) +#define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop) +#define DISABLE_WARNING(warningCode) DO_PRAGMA(GCC diagnostic ignored #warningCode) // expects arg name for clang and gnu compilers +#define SUPPRESS_ANALYSIS_WARNING(warningCode) // gnu doesn't support per-instance static analyzer warning suppression + +#define SUPPRESS_WARNING_NULL_PTR_DEREFERENCE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMORY +#define SUPPRESS_WARNING_EXPRESSION_NOT_TRUE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMBER +#define SUPPRESS_WARNING_UNNAMED_CUSTOM_OBJ + + +#elif defined(__clang__) + +#define DO_PRAGMA(X) _Pragma(#X) +#define DISABLE_WARNING_PUSH DO_PRAGMA(GCC diagnostic push) +#define DISABLE_WARNING_POP DO_PRAGMA(GCC diagnostic pop) +#define DISABLE_WARNING(warningCode) DO_PRAGMA(GCC diagnostic ignored #warningCode) // expects arg name for clang and gnu compilers +#define SUPPRESS_ANALYSIS_WARNING(warningCode) // clang doesn't support per-instance static analyzer warning suppression + +#define SUPPRESS_WARNING_NULL_PTR_DEREFERENCE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMORY +#define SUPPRESS_WARNING_EXPRESSION_NOT_TRUE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMBER +#define SUPPRESS_WARNING_UNNAMED_CUSTOM_OBJ + + +// default for non-defined platforms +#else + +#define DISABLE_WARNING_PUSH +#define DISABLE_WARNING_POP +#define DISABLE_WARNING(warningCode) + +#define SUPPRESS_WARNING_NULL_PTR_DEREFERENCE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMORY +#define SUPPRESS_WARNING_EXPRESSION_NOT_TRUE +#define SUPPRESS_WARNING_UNINITIALIZED_MEMBER +#define SUPPRESS_WARNING_UNNAMED_CUSTOM_OBJ + + +#endif \ No newline at end of file diff --git a/Source/Shared/string_array.h b/Source/Shared/string_array.h index 42a8b060..7707af43 100644 --- a/Source/Shared/string_array.h +++ b/Source/Shared/string_array.h @@ -9,10 +9,10 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN class UTF8StringArray { public: - UTF8StringArray(const xsapi_internal_vector& vector) + UTF8StringArray(const xsapi_internal_vector& vector) { std::transform(vector.begin(), vector.end(), std::back_inserter(m_strings), - [](const string_t& in) + [](const xsapi_internal_string& in) { return Make(in); }); diff --git a/Source/Shared/telemetry.cpp b/Source/Shared/telemetry.cpp deleted file mode 100644 index cba0092f..00000000 --- a/Source/Shared/telemetry.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" -#include "telemetry.h" -#include "xbox_system_factory.h" -#include "xbox_live_app_config_internal.h" -#include "Xal/xal_internal_telemetry.h" - -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN10 - -#define TraceLoggingOptionMicrosoftTelemetry() \ - TraceLoggingOptionGroup(0x4f50731a, 0x89cf, 0x4782, 0xb3, 0xe0, 0xdc, 0xe8, 0xc9, 0x4, 0x76, 0xba) - -TRACELOGGING_DEFINE_PROVIDER( - g_hTraceLoggingProvider, - "Microsoft.Xbox.Services", - (0xe8f7748f, 0xd38f, 0x4f0d, 0x8f, 0x5d, 0x9, 0xe, 0x39, 0x18, 0xfc, 0xd6), // {E8F7748F-D38F-4F0D-8F5D-090E3918FCD6} - TraceLoggingOptionMicrosoftTelemetry()); - -TRACELOGGING_DEFINE_PROVIDER( - g_hUnitTestTraceLoggingProvider, - "Microsoft.Xbox.Services.Tracing", - (0x9594a560, 0xe985, 0x4ee6, 0xb0, 0xb5, 0xd, 0xac, 0x4f, 0x92, 0x41, 0x44), // {9594A560-E985-4EE6-B0B5-0DAC4F924144} - ); - -#endif - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -std::atomic xsapi_telemetry::s_ticketId(0); - -std::shared_ptr xsapi_telemetry::get_singleton() -{ - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - if (xsapiSingleton) - { - std::lock_guard guard(xsapiSingleton->m_telemetryLock); - if (xsapiSingleton->m_telemetrySingleton == nullptr) - { - auto buffer = Alloc(sizeof(xsapi_telemetry)); - - xsapiSingleton->m_telemetrySingleton = std::shared_ptr( - new (buffer) xsapi_telemetry(), - Deleter() - ); - } - return xsapiSingleton->m_telemetrySingleton; - } - else - { - return nullptr; - } -} - -void xsapi_telemetry::write_event(xbox_live_user_t user, xsapi_internal_string eventName, xsapi_internal_string jsonPayload, bool isRealtimeEvent) -{ -#if HC_PLATFORM != HC_PLATFORM_GDK && !XSAPI_UNIT_TESTS // TODO: GDK - try - { - // Check event name - regex_t regex(_T("[A-Za-z]+[A-Za-z0-9_]*")); - bool matchFound = std::regex_match(utils::string_t_from_internal_string(eventName), regex); - if (!matchFound) - { - throw std::invalid_argument("Invalid event name!"); - } - - auto fullEventName = - "Microsoft.XboxLive.T" + - std::to_string( AppConfig::Instance()->TitleId() ) + - "." + - eventName.data(); - - XalTelemetryTicket tickets[] = - { - { "https://vortex-win.data.microsoft.com", 0, XalTelemetryTicketType_XauthDevice }, - { "https://vortex-events.xboxlive.com", s_ticketId++, XalTelemetryTicketType_XauthUser } - }; - - XalTelemetryWriteEvent( - user, - m_iKey.c_str(), - fullEventName.c_str(), - jsonPayload.c_str(), - sizeof(tickets) / sizeof(XalTelemetryTicket), - tickets, - isRealtimeEvent ? XalTelemetryLatency_Realtime : XalTelemetryLatency_Normal, - XalTelemetryPersistence_Normal, - XalTelemetrySensitivity_None, - XalTelemetrySampleRate_Unspecified - ); - } - catch (const std::exception&) - { - xbl_error_code err = utils::convert_exception_to_xbox_live_error_code(); - xsapi_internal_stringstream ss; - ss << "Exception in " << __FUNCTION__ << ": " << err; - LOG_ERROR(ss.str().data()); - } -#else - UNREFERENCED_PARAMETER(user); - UNREFERENCED_PARAMETER(eventName); - UNREFERENCED_PARAMETER(jsonPayload); - UNREFERENCED_PARAMETER(isRealtimeEvent); -#endif -} - -xsapi_telemetry::xsapi_telemetry() -{ -#if !(HC_PLATFORM == HC_PLATFORM_XDK) - xsapi_internal_stringstream defaultIKey; - defaultIKey << "P-XBL-T" << AppConfig::Instance()->TitleId(); - m_iKey = defaultIKey.str(); -#endif -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - diff --git a/Source/Shared/telemetry.h b/Source/Shared/telemetry.h deleted file mode 100644 index 0dd6bd26..00000000 --- a/Source/Shared/telemetry.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma once -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN10 - -#include - -#define XSAPI_TELEMETRY_KEYWORDS 0x0000400000000000 -TRACELOGGING_DECLARE_PROVIDER(g_hTraceLoggingProvider); -TRACELOGGING_DECLARE_PROVIDER(g_hUnitTestTraceLoggingProvider); - -#else - -#define TraceLoggingWrite(hProvider, eventName, ...) void(0) -#define TraceLoggingUnregister(hProvider) void(0) -#define TraceLoggingRegister(hProvider) void(0) - -#endif - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - -class xsapi_telemetry -{ -public: - static std::shared_ptr get_singleton(); - - void write_event(xbox_live_user_t user, xsapi_internal_string eventName, xsapi_internal_string jsonPayload, bool isRealtimeEvent = false); - -#if HC_PLATFORM == HC_PLATFORM_ANDROID - static void write_event_jni(JNIEnv *, jclass, jstring jsonPayload); - - static bool register_natives(JNIEnv *env, jobject clsLoader, jmethodID loadClass); -#endif -private: - xsapi_telemetry(); - - xsapi_internal_string m_iKey; - static std::atomic s_ticketId; -}; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/Shared/uri_impl.h b/Source/Shared/uri_impl.h new file mode 100644 index 00000000..f9b65b13 --- /dev/null +++ b/Source/Shared/uri_impl.h @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#pragma once + +#include "HookedUri/details/asyncrt_utils.hpp" +#include "HookedUri/details/uri.hpp" +#include "HookedUri/details/uri_builder.hpp" +#include "HookedUri/details/uri_parser.hpp" + diff --git a/Source/Shared/user.cpp b/Source/Shared/user.cpp index 55b08308..2654e351 100644 --- a/Source/Shared/user.cpp +++ b/Source/Shared/user.cpp @@ -10,6 +10,7 @@ User::User(XblUserHandle userHandle) noexcept : m_handle(userHandle) {} + User::User(User&& other) noexcept : m_handle{ other.m_handle }, m_localId { std::move(other.m_localId) }, m_xuid {other.m_xuid } { @@ -54,6 +55,12 @@ User::~User() noexcept /*static*/ Result User::WrapHandle(XblUserHandle userHandle) noexcept { + if (XblShouldFaultInject(INJECTION_FEATURE_USER)) + { + LOGS_ERROR << "FAULT INJECTION: User::WrapHandle ID:" << XblGetFaultCounter(); + return Result{ User(nullptr), E_FAIL }; + } + if (userHandle == nullptr) { return Result{ User(nullptr), E_INVALIDARG }; @@ -139,6 +146,12 @@ HRESULT User::InitializeUser() noexcept Result User::Copy() const noexcept { + if (XblShouldFaultInject(INJECTION_FEATURE_USER)) + { + LOGS_ERROR << "FAULT INJECTION: User::Copy ID:" << XblGetFaultCounter(); + return Result{ User(nullptr), E_FAIL }; + } + XalUserHandle copiedHandle; auto hr = XalUserDuplicateHandle(this->m_handle, &copiedHandle); if (FAILED(hr)) @@ -162,7 +175,7 @@ uint64_t User::Xuid() const noexcept uint64_t User::LocalId() const noexcept { XalUserLocalId localId{ 0 }; - if (m_handle != nullptr) + if (m_handle != nullptr && !XblShouldFaultInject(INJECTION_FEATURE_USER)) { auto hr = XalUserGetLocalId(m_handle, &localId); if (SUCCEEDED(hr)) @@ -236,6 +249,12 @@ HRESULT User::GetTokenAndSignature( AsyncContext>&& async ) noexcept { + if (XblShouldFaultInject(INJECTION_FEATURE_USER)) + { + LOGS_ERROR << "FAULT INJECTION: User::GetTokenAndSignature ID:" << XblGetFaultCounter(); + return E_FAIL; + } + bool forceRefresh{ false }; auto state{ GlobalState::Get() }; @@ -337,16 +356,24 @@ Result User::RegisterChangeEventHandler( XalRegistrationToken token{}; auto context{ MakeShared(std::move(handler)) }; - auto hr = XalUserRegisterChangeEventHandler( - TaskQueue().GetHandle(), - context.get(), - [](void* context, UserLocalId userId, UserChangeType change) - { - auto handler{ static_cast(context) }; - (*handler)(std::move(userId), std::move(static_cast(change))); - }, - &token - ); + auto hr = E_FAIL; + if (!XblShouldFaultInject(INJECTION_FEATURE_USER)) + { + hr = XalUserRegisterChangeEventHandler( + TaskQueue().GetHandle(), + context.get(), + [](void* context, UserLocalId userId, UserChangeType change) + { + auto handler{ static_cast(context) }; + (*handler)(std::move(userId), std::move(static_cast(change))); + }, + &token + ); + } + else + { + LOGS_ERROR << "FAULT INJECTION: User::RegisterChangeEventHandler ID:" << XblGetFaultCounter(); + } if (SUCCEEDED(hr)) { @@ -379,7 +406,7 @@ Result User::GetGamertagComponent( { size_t size = XalUserGetGamertagSize(m_handle, component); - std::vector gamertagComponent(size, char{}); + Vector gamertagComponent(size, char{}); auto hr = XalUserGetGamertag(m_handle, component, size, &gamertagComponent[0], nullptr); if (SUCCEEDED(hr)) { diff --git a/Source/Shared/user.h b/Source/Shared/user.h index a303e471..9486b390 100644 --- a/Source/Shared/user.h +++ b/Source/Shared/user.h @@ -76,7 +76,7 @@ private: User(XblUserHandle userHandle) noexcept; HRESULT InitializeUser() noexcept; - Result GetGamertagComponent(XalGamertagComponent component) const noexcept; + Result GetGamertagComponent(XalGamertagComponent component) const noexcept; XblUserHandle m_handle{ nullptr }; mutable uint64_t m_xuid; mutable XalUserLocalId m_localId; diff --git a/Source/Shared/utils_locales.cpp b/Source/Shared/utils_locales.cpp index e70792ee..04038757 100644 --- a/Source/Shared/utils_locales.cpp +++ b/Source/Shared/utils_locales.cpp @@ -196,7 +196,7 @@ xsapi_internal_vector utils::get_locale_list() #endif -void utils::generate_locales() +String utils::generate_locales() { xsapi_internal_vector localeList = get_locale_list(); xsapi_internal_vector localeFallbackList; @@ -216,61 +216,27 @@ void utils::generate_locales() nPos = locale.rfind("-", nPos - 1); } } - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - if (xsapiSingleton != nullptr) + + String locales{}; + for (auto& locale : localeFallbackList) { - xsapiSingleton->m_locales.clear(); - for (auto& locale : localeFallbackList) - { - xsapiSingleton->m_locales += locale; - xsapiSingleton->m_locales += ','; - } - // erase the last ',' - xsapiSingleton->m_locales.pop_back(); + locales += locale; + locales += ','; } + // erase the last ',' + locales.pop_back(); + + return locales; } -xsapi_internal_string utils::get_locales() +String utils::get_locales() { - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - if (!xsapiSingleton) + auto state = GlobalState::Get(); + if (state) { - LOGS_DEBUG << "utils::get_locales called while global state is not initalized"; - - // Fallback to English only - return xsapi_internal_string{ "en-US" }; - } - - std::lock_guard guard(xsapiSingleton->m_locale_lock); - if (xsapiSingleton->m_custom_locale_override) - { - return xsapiSingleton->m_locales; - } - // For WinRT app, locale can only be get from STA, thus we generate locale in UI dispatcher assignment. - // For desktop and xbox, we generate locale on the first call. -#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_GDK - static bool s_localeGenerated = false; - if (!s_localeGenerated) - { - generate_locales(); - s_localeGenerated = true; - } -#endif - - return xsapiSingleton->m_locales; -} - - -void utils::set_locales( - _In_ const xsapi_internal_string& locale - ) -{ - auto xsapiSingleton = xbox::services::get_xsapi_singleton(); - if (xsapiSingleton != nullptr) - { - xsapiSingleton->m_locales = locale; - xsapiSingleton->m_custom_locale_override = true; + return state->Locales().data(); } + return String{ "en-US" }; } NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/Shared/web_socket.cpp b/Source/Shared/web_socket.cpp index cb47b763..d23dc629 100644 --- a/Source/Shared/web_socket.cpp +++ b/Source/Shared/web_socket.cpp @@ -35,11 +35,18 @@ HRESULT Websocket::Connect( _In_ const String& subProtocol ) noexcept { + auto state = GlobalState::Get(); + if (!state) + { + return E_XBL_NOT_INITIALIZED; + } + m_user.GetTokenAndSignature("GET", uri, HttpHeaders{}, nullptr, 0, false, AsyncContext>{ m_queue.GetHandle(), [ uri = String{ uri }, subProtocol = String{ subProtocol }, + locales = state->Locales(), weakThis{ std::weak_ptr{ shared_from_this() } } ] (Result authResult) @@ -61,7 +68,7 @@ HRESULT Websocket::Connect( HCWebSocketSetHeader(sharedThis->m_hcWebsocket, "Authorization", authPayload.token.data()); HCWebSocketSetHeader(sharedThis->m_hcWebsocket, "Signature", authPayload.signature.data()); - HCWebSocketSetHeader(sharedThis->m_hcWebsocket, "Accept-Language", utils::get_locales().data()); + HCWebSocketSetHeader(sharedThis->m_hcWebsocket, "Accept-Language", locales.data()); xsapi_internal_string userAgent = DEFAULT_USER_AGENT; HCWebSocketSetHeader(sharedThis->m_hcWebsocket, "User-Agent", userAgent.data()); diff --git a/Source/Shared/xbox_live_app_config.cpp b/Source/Shared/xbox_live_app_config.cpp index 7b9108f2..6e8a93c8 100644 --- a/Source/Shared/xbox_live_app_config.cpp +++ b/Source/Shared/xbox_live_app_config.cpp @@ -6,7 +6,6 @@ #include "xbox_live_app_config_internal.h" #if HC_PLATFORM == HC_PLATFORM_UWP #include "local_config.h" -#include "xbox_system_factory.h" #endif using namespace xbox::services; @@ -15,15 +14,12 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN std::shared_ptr AppConfig::Instance() { - auto xsapiSingleton{ xbox::services::get_xsapi_singleton() }; - if (xsapiSingleton) + auto state = GlobalState::Get(); + if (state) { - return xsapiSingleton->m_appConfigSingleton; - } - else - { - return nullptr; + return state->AppConfig(); } + return nullptr; } #if HC_PLATFORM == HC_PLATFORM_UWP diff --git a/Source/Shared/xbox_live_app_config_internal.h b/Source/Shared/xbox_live_app_config_internal.h index c6b3a5d2..eda56e62 100644 --- a/Source/Shared/xbox_live_app_config_internal.h +++ b/Source/Shared/xbox_live_app_config_internal.h @@ -15,6 +15,7 @@ class AppConfig : public std::enable_shared_from_this public: AppConfig() = default; + // TODO Remove. Unsafe method - returns null if GlobalState doesn't exist and is unchecked by callers static std::shared_ptr Instance(); #if HC_PLATFORM == HC_PLATFORM_UWP || HC_PLATFORM == HC_PLATFORM_XDK diff --git a/Source/Shared/xbox_live_services_settings.cpp b/Source/Shared/xbox_live_services_settings.cpp deleted file mode 100644 index 7f0923b5..00000000 --- a/Source/Shared/xbox_live_services_settings.cpp +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" -#include "xbox_live_services_settings.h" -#include "Logger/log_hc_output.h" - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN - -std::function<_Ret_maybenull_ _Post_writable_byte_size_(dwSize) void*(_In_ size_t dwSize)> g_pCppMemAllocHook = nullptr; -std::function g_pCppMemFreeHook = nullptr; - -std::shared_ptr xbox_live_services_settings::get_singleton_instance(_In_ bool createIfRequired) -{ - UNREFERENCED_PARAMETER(createIfRequired); - - std::shared_ptr xsapiSingleton = get_xsapi_singleton(); - if (xsapiSingleton == nullptr) - { - return nullptr; - } - - { - std::lock_guard guard(xsapiSingleton->m_serviceSettingsLock); - if (xsapiSingleton->m_xboxServiceSettingsSingleton == nullptr) - { - xsapiSingleton->m_xboxServiceSettingsSingleton = std::shared_ptr(new xbox_live_services_settings()); - } - return xsapiSingleton->m_xboxServiceSettingsSingleton; - } -} - -xbox_live_services_settings::xbox_live_services_settings() : - m_traceLevel(xbox_services_diagnostics_trace_level::off), - m_loggingHandlersCounter(0), - m_wnsHandlersCounter(0) -{ -} - -void *custom_mem_alloc_wrapper(_In_ size_t size, _In_ uint32_t memoryType) -{ - UNREFERENCED_PARAMETER(memoryType); - if (g_pCppMemAllocHook == nullptr) - { - XSAPI_ASSERT(true && L"Custom mem hook function not set!"); - return nullptr; - } - else - { - try - { - return g_pCppMemAllocHook(size); - } - catch (...) - { - LOG_ERROR("mem_alloc callback failed."); - return nullptr; - } - } -} - -void custom_mem_free_wrapper(_In_ void *pointer, _In_ uint32_t memoryType) -{ - UNREFERENCED_PARAMETER(memoryType); - if (g_pCppMemFreeHook == nullptr) - { - XSAPI_ASSERT(true && L"Custom mem hook function not set!"); - return; - } - else - { - try - { - return g_pCppMemFreeHook(pointer); - } - catch (...) - { - LOG_ERROR("mem_free callback failed."); - } - } -} - -void xbox_live_services_settings::set_memory_allocation_hooks( - _In_ const std::function<_Ret_maybenull_ _Post_writable_byte_size_(dwSize) void*(_In_ size_t dwSize)>& memAllocHandler, - _In_ const std::function& memFreeHandler - ) -{ - // Both params must either be null or both must be non-null - if (memAllocHandler != nullptr || memFreeHandler != nullptr) - { - THROW_CPP_INVALIDARGUMENT_IF(memAllocHandler == nullptr || memFreeHandler == nullptr); - } - - g_pCppMemAllocHook = memAllocHandler; - g_pCppMemFreeHook = memFreeHandler; - - g_pMemAllocHook = (g_pCppMemAllocHook == nullptr) ? nullptr : custom_mem_alloc_wrapper; - g_pMemFreeHook = (g_pCppMemFreeHook == nullptr) ? nullptr : custom_mem_free_wrapper; - - HCMemSetFunctions(g_pMemAllocHook, g_pMemFreeHook); -} - -function_context xbox_live_services_settings::add_logging_handler(_In_ std::function handler) -{ - std::lock_guard lock(m_loggingWriteLock); - - function_context context = 0; - if (handler != nullptr) - { - context = (function_context)(uint64_t)(++m_loggingHandlersCounter); - m_loggingHandlers[m_loggingHandlersCounter] = std::move(handler); - } - - return context; -} - -void xbox_live_services_settings::remove_logging_handler(_In_ function_context context) -{ - std::lock_guard lock(m_loggingWriteLock); - m_loggingHandlers.erase((uint32_t)(uint64_t)context); -} - -function_context xbox_live_services_settings::add_wns_handler(_In_ const std::function& handler) -{ - - function_context context = 0; - if (handler != nullptr) - { - context = (function_context)(uint64_t)(++m_wnsHandlersCounter); - m_wnsHandlers[m_wnsHandlersCounter] = handler; - } - - return context; -} - -void xbox_live_services_settings::remove_wns_handler(_In_ function_context context) -{ - std::lock_guard lock(m_wnsEventLock); - m_wnsHandlers.erase((uint32_t)(uint64_t)context); -} - -xbox_services_diagnostics_trace_level xbox_live_services_settings::diagnostics_trace_level() const -{ - return m_traceLevel; -} - -void xbox_live_services_settings::set_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level value) -{ - m_traceLevel = value; - set_log_level_from_diagnostics_trace_level(); -} - -void xbox_live_services_settings::_Raise_logging_event(_In_ xbox_services_diagnostics_trace_level level, _In_ const std::string& category, _In_ const std::string& message) -{ - std::lock_guard lock(m_loggingWriteLock); - - for (auto& handler : m_loggingHandlers) - { - XSAPI_ASSERT(handler.second != nullptr); - if (handler.second != nullptr) - { - try - { - handler.second(level, category, message); - } - catch (...) - { - LOG_ERROR("xbox_live_services_settings::raise_logging_event failed."); - } - } - } -} - -void xbox_live_services_settings::_Raise_wns_event( - _In_ const string_t& xbox_user_id, - _In_ const string_t& notification_type, - _In_ const string_t& content -) -{ - std::lock_guard lock(m_wnsEventLock); - - xbox_live_wns_event_args arg(xbox_user_id, notification_type, content); - for (auto& handler : m_wnsHandlers) - { - XSAPI_ASSERT(handler.second != nullptr); - if (handler.second != nullptr) - { - try - { - handler.second(arg); - } - catch (...) - { - LOG_ERROR("xbox_live_services_settings::raise_wns_event failed."); - } - } - } -} - -bool xbox_live_services_settings::_Is_at_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level level) -{ - return (int)m_traceLevel >= (int)level; -} - -void xbox_live_services_settings::set_log_level_from_diagnostics_trace_level() -{ - HCTraceLevel logLevel = HCTraceLevel::Off; - switch (m_traceLevel) - { - case xbox_services_diagnostics_trace_level::off: logLevel = HCTraceLevel::Off; break; - case xbox_services_diagnostics_trace_level::error: logLevel = HCTraceLevel::Error; break; - case xbox_services_diagnostics_trace_level::warning: logLevel = HCTraceLevel::Warning; break; - case xbox_services_diagnostics_trace_level::info: logLevel = HCTraceLevel::Information; break; - case xbox_services_diagnostics_trace_level::verbose: logLevel = HCTraceLevel::Verbose; break; - } - logger::get_logger()->set_log_level(logLevel); -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END diff --git a/Source/Shared/xbox_live_services_settings.h b/Source/Shared/xbox_live_services_settings.h deleted file mode 100644 index d8cbe40f..00000000 --- a/Source/Shared/xbox_live_services_settings.h +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma once -#include "internal_types.h" - -#ifdef __OBJC__ -#import -#endif -#if !HC_PLATFORM_IS_MICROSOFT && !XSAPI_NO_PPL -#include "pplx/pplxtasks.h" -#endif - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -class XboxLiveContextSettings; - -/// -/// Enumeration values that indicate the trace levels of debug output for service diagnostics. -/// -/// Setting the debug trace level to error or higher reports the last HRESULT, the current -/// function, the source file, and the line number for many trace points in the Xbox live code. -/// -enum class xbox_services_diagnostics_trace_level -{ - /// - /// Output no tracing and debugging messages. - /// - off, - - /// - /// Output error-handling messages. - /// - error, - - /// - /// Output warnings and error-handling messages. - /// - warning, - - /// - /// Output informational messages, warnings, and error-handling messages. - /// - info, - - /// - /// Output all debugging and tracing messages. - /// - verbose -}; - - -#if !XSAPI_UNIT_TESTS && !XSAPI_NO_PPL -namespace events { - class events_service; -} -#endif - -namespace multiplayer { - namespace manager { - class multiplayer_client_manager; - } -} -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -/// -/// Configuration information for Xbox Live service objects. -/// -namespace system { - - // Forward declaration - class sign_out_completed_event_args; - class user_impl; - class token_and_signature_result_internal; - class user_factory; - class xbox_live_server_impl; - class auth_config; - - class xbox_live_wns_event_args - { - public: - /// - /// Returns the xbox user id for the WNS event - /// - _XSAPIIMP const string_t& xbox_user_id() const { return m_xbox_user_id; } - - /// - /// Returns the notification type - /// - _XSAPIIMP const string_t& notification_type() const { return m_notification_type; } - - /// - /// Returns the full notification content - /// - _XSAPIIMP const string_t& notification_content() const { return m_notification_content; } - - /// - /// Internal function - /// - xbox_live_wns_event_args( - _In_ string_t xbox_user_id, - _In_ string_t notification_type, - _In_ string_t notification_content - ) : - m_xbox_user_id(std::move(xbox_user_id)), - m_notification_type(std::move(notification_type)), - m_notification_content(std::move(notification_content)) - {} - - private: - string_t m_xbox_user_id; - string_t m_notification_type; - string_t m_notification_content; - }; - - class xbox_live_services_settings : public std::enable_shared_from_this - { - public: - /// - /// Gets the singleton instance - /// - _XSAPIIMP static std::shared_ptr get_singleton_instance(_In_ bool createIfRequired = true); - - /// - /// Used by titles to register memory allocation hooks that are used by XSAPI when it - /// needs to allocate a large block of memory such as SocialManager which uses a large block - /// of memory to keep track of the friends list. - /// - /// Note that not all memory that XSAPI uses goes through this allocator (for example std::string), - /// but these allocations are typically small and transient. - /// - /// The title's allocation function. Input is size of memory block that's being requested. Return is pointer to the allocated memory block - /// The title's memory free function. Input is address of memory to free - /// - /// If titles choose not to provide their own allocation hooks, these system default allocators will be used instead. - /// To unwire your hooks, call the same routine with nullptr passed in for both parameters. - /// It is important to provide an implementation for both memAllocHandler and memFreeHandler if you hook them; - /// hooking only one of them will be considered an error. - /// - _XSAPIIMP static void set_memory_allocation_hooks( - _In_ const std::function<_Ret_maybenull_ _Post_writable_byte_size_(dwSize) void* (_In_ size_t dwSize)>& memAllocHandler, - _In_ const std::function& memFreeHandler - ); - - /// - /// Registers to receive logging messages for levels that are enabled. Event handlers will receive the level, category, and content of the message. - /// - /// The event handler function to call. - /// - /// A function_context object that can be used to unregister the event handler. - /// - _XSAPIIMP function_context add_logging_handler(_In_ std::function handler); - - /// - /// Unregisters from receiving logging messages. - /// - /// The function_context object that was returned when the event handler was registered. - _XSAPIIMP void remove_logging_handler(_In_ function_context context); - - /// - /// Indicates the level of debug messages to send to the debugger's Output window. - /// - _XSAPIIMP xbox_services_diagnostics_trace_level diagnostics_trace_level() const; - - /// - /// Sets the level of debug messages to send to the debugger's Output window. - /// - _XSAPIIMP void set_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level value); - - /// - /// Registers to receive Windows Push Notification Service(WNS) events. Event handlers will receive the xbox user id and notification type. - /// - /// The event handler function to call. - /// - /// A function_context object that can be used to unregister the event handler. - /// - _XSAPIIMP function_context add_wns_handler(_In_ const std::function& handler); - - /// - /// Unregisters from receiving Windows Push Notification Service(WNS) events. - /// - /// The function_context object that was returned when the event handler was registered. - _XSAPIIMP void remove_wns_handler(_In_ function_context context); - - /// - /// Internal function - /// - void _Raise_logging_event(_In_ xbox_services_diagnostics_trace_level level, _In_ const std::string& category, _In_ const std::string& message); - - /// - /// Internal function - /// - void _Raise_wns_event(_In_ const string_t& xbox_user_id, _In_ const string_t& nofitication_type, _In_ const string_t& content); - - /// - /// Internal function - /// - bool _Is_at_diagnostics_trace_level(_In_ xbox_services_diagnostics_trace_level level); - - private: - xbox_live_services_settings(); - - void set_log_level_from_diagnostics_trace_level(); - - xbox_services_diagnostics_trace_level m_traceLevel; - std::mutex m_loggingWriteLock; - std::unordered_map> m_loggingHandlers; - uint32_t m_loggingHandlersCounter{ 1 }; - - std::mutex m_wnsEventLock; - std::unordered_map> m_wnsHandlers; - uint32_t m_wnsHandlersCounter{ 1 }; - - friend class xsapi_memory; - friend void* custom_mem_alloc_wrapper(_In_ size_t size, _In_ uint32_t memoryType); - friend void custom_mem_free_wrapper(_In_ void* pointer, _In_ uint32_t memoryType); - }; -} // namespace system - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - - diff --git a/Source/Shared/xbox_system_factory.cpp b/Source/Shared/xbox_system_factory.cpp deleted file mode 100644 index 74ebe30d..00000000 --- a/Source/Shared/xbox_system_factory.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" -#include "xbox_system_factory.h" -#include "xbox_live_context_internal.h" -#include "xsapi-c/http_call_c.h" -#include "http_call_legacy.h" - -using namespace xbox::services::legacy; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN -xbox_live_user_t xbox_system_factory::httpCallUserHandle; -std::shared_ptr -xbox_system_factory::create_http_call( - _In_ const std::shared_ptr& xboxLiveContextSettings, - _In_ const string_t& _httpMethod, - _In_ const string_t& _serverName, - _In_ const xbox::services::uri& pathQueryFragment, - _In_ xbox_live_api xboxLiveApi -) -{ - UNREFERENCED_PARAMETER(xboxLiveContextSettings); - UNREFERENCED_PARAMETER(xboxLiveApi); - if (xbox_system_factory::httpCallUserHandle == 0) - { - return nullptr; - } - - auto httpMethod_str = StringFromStringT(_httpMethod); - auto fullUrl = _serverName; - if (!pathQueryFragment.is_empty()) - { - fullUrl += pathQueryFragment.to_string(); - } - auto fullUrl_str = StringFromStringT(fullUrl); - XblContextHandle contextHandle; - XblContextCreateHandle(xbox_system_factory::httpCallUserHandle, &contextHandle); - - - XblHttpCallHandle callHandle; - auto hr = XblHttpCallCreate(contextHandle, httpMethod_str.c_str(), fullUrl_str.c_str(), &callHandle); - XblContextCloseHandle(contextHandle); - - if (FAILED(hr)) - { - return nullptr; - } - - web::uri_builder builder; - builder.append(pathQueryFragment.to_string()); - web::uri tempPathQuery = builder.to_uri(); - return std::make_shared(callHandle, _httpMethod, _serverName, tempPathQuery); -} - -std::shared_ptr -xbox_system_factory::get_factory() -{ - auto xsapiSingleton{ xbox::services::get_xsapi_singleton() }; - if (xsapiSingleton) - { - return xsapiSingleton->m_factoryInstance; - } - else - { - assert(false); - return nullptr; - } -} - -void xbox_system_factory::set_factory( - _In_ std::shared_ptr factory - ) -{ - auto xsapiSingleton = get_xsapi_singleton(); - if (xsapiSingleton != nullptr) - { - std::lock_guard hold(xsapiSingleton->m_singletonLock); - xsapiSingleton->m_factoryInstance = factory; - } -} - -/*static*/ void xbox_system_factory::set_http_call_user(xbox_live_user_t user) -{ - xbox_system_factory::httpCallUserHandle = user; -} -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END diff --git a/Source/Shared/xbox_system_factory.h b/Source/Shared/xbox_system_factory.h deleted file mode 100644 index 0e97b2a6..00000000 --- a/Source/Shared/xbox_system_factory.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma once -#include "shared_macros.h" -#include "web_socket.h" -#include "multiplayer_internal.h" -#if HC_PLATFORM == HC_PLATFORM_UWP -#include "local_config.h" -#endif -#include - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN -namespace legacy -{ - class http_call; -} -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN - - - -class xbox_system_factory -{ -public: - // temporary method to support http call initialization in android jni layer without xalUserHandle - // TODo: remove it in the future - std::shared_ptr create_http_call( - _In_ const std::shared_ptr& xboxLiveContextSettings, - _In_ const string_t& httpMethod, - _In_ const string_t& serverName, - _In_ const xbox::services::uri& pathQueryFragment, - _In_ xbox_live_api xboxLiveApi - ); - - static std::shared_ptr get_factory(); - static void set_factory(_In_ std::shared_ptr factory); - - static void set_http_call_user(xbox_live_user_t user); - - virtual ~xbox_system_factory() = default; - -private: - static xbox_live_user_t httpCallUserHandle; -}; - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END diff --git a/Source/Shared/xsapi_json_utils.cpp b/Source/Shared/xsapi_json_utils.cpp index abc59a05..c420a6ba 100644 --- a/Source/Shared/xsapi_json_utils.cpp +++ b/Source/Shared/xsapi_json_utils.cpp @@ -1,9 +1,6 @@ #include "pch.h" #include "xsapi_json_utils.h" -#include "rapidjson/writer.h" -#include "rapidjson/stringbuffer.h" - using namespace xbox::services::legacy; NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN @@ -35,7 +32,7 @@ HRESULT JsonUtils::ExtractJsonFieldAsString( HRESULT JsonUtils::ExtractJsonStringVector( _In_ const JsonValue& json, _In_ const xsapi_internal_string& name, - _Inout_ std::vector& outVector, + _Inout_ xsapi_internal_vector& outVector, _In_ bool required ) { @@ -50,21 +47,21 @@ HRESULT JsonUtils::ExtractJsonFieldAsString( } else if (!required) { - outVector = std::vector(); + outVector = xsapi_internal_vector(); return S_OK; } } - outVector = std::vector(); + outVector = xsapi_internal_vector(); return WEB_E_INVALID_JSON_STRING; } HRESULT JsonUtils::ExtractJsonStringVector( _In_ const JsonValue& json, - _Inout_ std::vector& outVector + _Inout_ xsapi_internal_vector& outVector ) { - outVector = std::vector(); + outVector = xsapi_internal_vector(); if (!json.IsArray()) { return WEB_E_INVALID_JSON_STRING; @@ -80,58 +77,6 @@ HRESULT JsonUtils::ExtractJsonFieldAsString( } return S_OK; - } - -HRESULT JsonUtils::ExtractJsonStringTVector( - _In_ const JsonValue& json, - _In_ const xsapi_internal_string& name, - _Inout_ std::vector& outVector, - _In_ bool required -) -{ - outVector = std::vector(); - if (json.IsObject()) - { - if (json.HasMember(name.c_str())) - { - return ExtractJsonStringTVector( - json[name.c_str()], - outVector - ); - } - else if (!required) - { - return S_OK; - } - } - - return WEB_E_INVALID_JSON_STRING; -} - - - -HRESULT JsonUtils::ExtractJsonStringTVector( - _In_ const JsonValue& json, - _Inout_ std::vector& outVector -) -{ - outVector = std::vector(); - - if (!json.IsArray()) - { - return WEB_E_INVALID_JSON_STRING; - } - - for (const auto& string : json.GetArray()) - { - if (!string.IsString()) - { - return WEB_E_INVALID_JSON_STRING; - } - outVector.push_back(utils::string_t_from_internal_string(string.GetString())); - } - - return S_OK; } Result JsonUtils::JsonStringExtractor(_In_ const JsonValue& json) @@ -143,15 +88,6 @@ Result JsonUtils::JsonStringExtractor(_In_ const JsonValu return Result(json.GetString()); } -Result JsonUtils::JsonStringTExtractor(_In_ const JsonValue& json) -{ - if (!json.IsString()) - { - return Result(WEB_E_INVALID_JSON_STRING); - } - return Result(utils::string_t_from_internal_string(json.GetString())); -} - void JsonUtils::JsonStringSerializer(_In_ const xsapi_internal_string& value, _Out_ JsonValue& json, JsonDocument::AllocatorType& allocator) { json.SetString(value.c_str(), allocator); @@ -246,45 +182,6 @@ HRESULT JsonUtils::ExtractJsonString( return WEB_E_INVALID_JSON_STRING; } -HRESULT JsonUtils::ExtractJsonString( - _In_ const JsonValue& jsonValue, - _In_ const xsapi_internal_string& stringName, - _Inout_ string_t& outString, - _In_ bool required -) -{ - xsapi_internal_string internalString; - RETURN_HR_IF_FAILED(ExtractJsonString(jsonValue, stringName, internalString, required)); - outString = utils::string_t_from_internal_string(internalString); - return S_OK; -} - -HRESULT -JsonUtils::ExtractJsonStringToCharTArray( - _In_ const JsonValue& jsonValue, - _In_ const xsapi_internal_string& stringName, - _In_reads_bytes_(size) char_t* charArr, - _In_ size_t size -) -{ - string_t jsonStr; - RETURN_HR_IF_FAILED(ExtractJsonString(jsonValue, stringName, jsonStr)); - uint32_t errorCode = 0; - -#if HC_PLATFORM_IS_MICROSOFT - auto strSize = __min(size - 1, jsonStr.size()); - wcsncpy_s(&charArr[0], size, jsonStr.c_str(), strSize); -#else - strncpy(&charArr[0], jsonStr.c_str(), size); -#endif - if (errorCode) - { - return WEB_E_INVALID_JSON_STRING; - } - - return S_OK; -} - HRESULT JsonUtils::ExtractJsonStringToCharArray( _In_ const JsonValue& jsonValue, _In_ const xsapi_internal_string& stringName, @@ -558,7 +455,7 @@ HRESULT JsonUtils::ExtractJsonUInt64( { //convert to wstring for use with xbox::services::datetime //xbox::services::datetime is still part of cpprestsdk - outTime = xbox::services::datetime::from_string(utils::string_t_from_internal_string(field.GetString()), xbox::services::datetime::date_format::ISO_8601); + outTime = xbox::services::datetime::from_string(field.GetString(), xbox::services::datetime::date_format::ISO_8601); return S_OK; } } @@ -647,7 +544,7 @@ HRESULT JsonUtils::ExtractJsonDouble( void JsonUtils::SerializeUInt52ToJson( _In_ uint64_t integer, - _Out_ JsonValue& json + _Inout_ JsonValue& json ) { if ((integer & 0xFFF0000000000000) != 0) @@ -664,7 +561,7 @@ JsonValue JsonUtils::SerializeTime( _In_ JsonDocument::AllocatorType& a ) noexcept { - auto timestampString = StringFromStringT(DatetimeFromTimeT(time).to_string(utility::datetime::ISO_8601)); + auto timestampString = DatetimeFromTimeT(time).to_string_internal(xbox::services::cppresturi::utility::datetime::ISO_8601); return JsonValue{ timestampString.data(), a }; } diff --git a/Source/Shared/xsapi_json_utils.h b/Source/Shared/xsapi_json_utils.h index d8d607a2..2b7e3bf5 100644 --- a/Source/Shared/xsapi_json_utils.h +++ b/Source/Shared/xsapi_json_utils.h @@ -33,21 +33,7 @@ public: _Inout_ xsapi_internal_string& outString, _In_ bool required = false ); - - static HRESULT ExtractJsonString( - _In_ const JsonValue& jsonValue, - _In_ const xsapi_internal_string& stringName, - _Inout_ string_t& outString, - _In_ bool required = false - ); - - static HRESULT ExtractJsonStringToCharTArray( - _In_ const JsonValue& jsonValue, - _In_ const xsapi_internal_string& stringName, - _In_reads_bytes_(size) char_t* charArr, - _In_ size_t size - ); - + static HRESULT ExtractJsonStringToCharArray( _In_ const JsonValue& jsonValue, _In_ const xsapi_internal_string& stringName, @@ -160,25 +146,13 @@ public: static HRESULT ExtractJsonStringVector( _In_ const JsonValue& json, _In_ const xsapi_internal_string& name, - _Inout_ std::vector& outVector, + _Inout_ xsapi_internal_vector& outVector, _In_ bool required ); static HRESULT ExtractJsonStringVector( _In_ const JsonValue& json, - _Inout_ std::vector& outVector - ); - - static HRESULT ExtractJsonStringTVector( - _In_ const JsonValue& json, - _In_ const xsapi_internal_string& name, - _Inout_ std::vector& outVector, - _In_ bool required - ); - - static HRESULT ExtractJsonStringTVector( - _In_ const JsonValue& json, - _Inout_ std::vector& outVector + _Inout_ xsapi_internal_vector& outVector ); template @@ -201,7 +175,7 @@ public: for (auto it = field.Begin(); it != field.End(); ++it) { auto obj = deserialize(*it); - if (obj.Hresult()) + if (Failed(obj)) { return obj.Hresult(); break; @@ -235,7 +209,7 @@ public: for (auto it = json.Begin(); it != json.End(); ++it) { auto obj = deserialize(*it); - if (obj.Hresult()) + if (Failed(obj)) { return obj.Hresult(); break; @@ -248,8 +222,6 @@ public: static Result JsonStringExtractor(_In_ const JsonValue& json); - static Result JsonStringTExtractor(_In_ const JsonValue& json); - static void JsonStringSerializer(_In_ const xsapi_internal_string& value, _Out_ JsonValue& json, _In_ JsonDocument::AllocatorType& allocator); static void JsonXuidSerializer(_In_ uint64_t xuid, _Out_ JsonValue& json, _In_ JsonDocument::AllocatorType& allocator); @@ -265,24 +237,6 @@ public: static void JsonIntSerializer(_In_ int32_t value, _Out_ JsonValue& json, _In_ JsonDocument::AllocatorType& UNUSED); - template - static void SerializeVector( - _In_ F serializer, - _In_ std::vector inputVector, - _Out_ JsonValue& jsonArray, - _In_ JsonDocument::AllocatorType& allocator - ) - { - jsonArray.SetArray(); - - for (auto& s : inputVector) - { - JsonValue val; - serializer(s, val, allocator); - jsonArray.PushBack(val, allocator); - } - } - template static void SerializeVector( _In_ F serializer, @@ -301,7 +255,7 @@ public: } } - static void SerializeUInt52ToJson(_In_ uint64_t integer, _Out_ JsonValue& json); + static void SerializeUInt52ToJson(_In_ uint64_t integer, _Inout_ JsonValue& json); static JsonValue SerializeTime( _In_ time_t time, diff --git a/Source/Shared/xsapi_utils.cpp b/Source/Shared/xsapi_utils.cpp index 9c83645e..21de05d2 100644 --- a/Source/Shared/xsapi_utils.cpp +++ b/Source/Shared/xsapi_utils.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #if !HC_PLATFORM_IS_MICROSOFT #include "xbl_guid.h" #elif defined(_WIN32) @@ -19,147 +20,27 @@ #include "presence_internal.h" #include "httpClient/httpClient.h" #include "Logger/log_hc_output.h" -#include "xbox_system_factory.h" #include "global_state.h" -HC_DEFINE_TRACE_AREA(XSAPI, HCTraceLevel::Verbose); +#ifndef _XTIME_TICKS_PER_TIME_T +#define _XTIME_TICKS_PER_TIME_T 10000000LL +#endif NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN #define MAKE_HTTP_HRESULT(code) MAKE_HRESULT(1, 0x019, code) -static const std::string _sdaPrefix = "AAAAAAAA"; +static char const * _sdaPrefix = "AAAAAAAA"; static const uint64_t _msTicks = static_cast(10000); static const uint64_t _secondTicks = 1000*_msTicks; -static std::recursive_mutex s_xsapiSingletonLock; -static std::shared_ptr s_xsapiSingleton; - -void CALLBACK XSAPI_HCTraceCallback( - _In_z_ const char* areaName, - _In_ HCTraceLevel level, - _In_ uint64_t threadId, - _In_ uint64_t timestamp, - _In_z_ const char* message - ) -{ - UNREFERENCED_PARAMETER(timestamp); - UNREFERENCED_PARAMETER(threadId); - UNREFERENCED_PARAMETER(areaName); - switch (level) - { - case HCTraceLevel::Error: LOG_ERROR(message); break; - case HCTraceLevel::Warning: LOG_WARN(message); break; - case HCTraceLevel::Important: LOG_WARN(message); break; - case HCTraceLevel::Information: LOG_INFO(message); break; - case HCTraceLevel::Verbose: LOG_DEBUG(message); break; - default: break; - } -} - -HRESULT xsapi_singleton::Initialize(_In_ const XblInitArgs* args) -{ - RETURN_HR_INVALIDARGUMENT_IF_NULL(args); - -#if HC_PLATFORM == HC_PLATFORM_UWP -#ifdef _WINRT_DLL - m_userEventBind = std::make_shared(); -#endif -#endif - -#if _DEBUG && XSAPI_UNIT_TESTS && XSAPI_PROFILE - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); -#endif - - // Configure logging -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN10 - // Create telemetry provider - TraceLoggingRegister(g_hTraceLoggingProvider); -#endif - m_logger = MakeShared(); - m_logger->add_log_output(std::make_shared()); - - m_deviceId = utils::create_guid(true); - - m_factoryInstance = MakeShared(); - -#if HC_PLATFORM == HC_PLATFORM_ANDROID - auto javaInteropInitResult = xbox::services::java_interop::get_java_interop_singleton()->initialize( - args->javaVM, - args->applicationContext - ); - if (javaInteropInitResult.err()) - { - return utils::convert_xbox_live_error_code_to_hresult(javaInteropInitResult.err()); - } -#endif - - m_appConfigSingleton = MakeShared(); - -#if HC_PLATFORM != HC_PLATFORM_XDK && HC_PLATFORM != HC_PLATFORM_UWP - RETURN_HR_INVALIDARGUMENT_IF_NULL(args->scid); - RETURN_HR_IF_FAILED(m_appConfigSingleton->Initialize(args->scid)); -#else - RETURN_HR_IF_FAILED(m_appConfigSingleton->Initialize()); -#endif - -#if HC_PLATFORM_IS_EXTERNAL - m_appConfigSingleton->SetAppId(args->appId); - m_appConfigSingleton->SetAppVer(args->appVer); - m_appConfigSingleton->SetOsName(args->osName); - m_appConfigSingleton->SetOsVersion(args->osVersion); - m_appConfigSingleton->SetOsLocale(args->osLocale); - m_appConfigSingleton->SetDeviceClass(args->deviceClass); - m_appConfigSingleton->SetDeviceId(args->deviceId); -#endif - -#if HC_PLATFORM == HC_PLATFORM_IOS - if(args->apnsEnvironment) - { - m_appConfigSingleton->SetAPNSEnvironment(args->apnsEnvironment); - } -#endif - - return S_OK; -} - -xsapi_singleton::~xsapi_singleton() -{ -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN10 - // Unregister telemetry provider - TraceLoggingUnregister(g_hTraceLoggingProvider); -#endif - - HCTraceSetClientCallback(nullptr); -} - -XTaskQueueHandle get_xsapi_singleton_async_queue() -{ - auto state{ GlobalState::Get() }; - if (state) - { - return state->Queue().GetHandle(); - } - return nullptr; -} - -std::shared_ptr get_xsapi_singleton() -{ - auto state{ GlobalState::Get() }; - if (state) - { - return state->singleton; - } - return nullptr; -} - xsapi_internal_string utils::encode_uri( _In_ const xsapi_internal_string& data, _In_ xbox::services::uri::components::component component ) { - return utils::internal_string_from_string_t(xbox::services::uri::encode_uri(utils::string_t_from_internal_string(data), component)); + return xbox::services::uri::encode_uri(data, component); } xsapi_internal_string utils::headers_to_string( @@ -176,34 +57,6 @@ xsapi_internal_string utils::headers_to_string( return ss.str(); } -web::http::http_headers utils::string_to_headers( - _In_ const string_t& headers - ) -{ - web::http::http_headers headerMap; - std::vector lines = utils::string_split(headers, '\n'); - - for (const auto& line : lines) - { - static regex_t headerLineRegex(_T("\\s*(\\S+):\\s*(.*\\S)\\s*")); - smatch_t match; - bool succeeded = std::regex_match(line, match, headerLineRegex); - if (succeeded) - { - // match[0] is the full matched string - // match[1] is the header name - // match[2] is the header value - headerMap[match[1]] = match[2]; - } - else if (!line.empty()) - { - LOGS_ERROR << "Parsing string to headers failed" << line; - } - } - - return headerMap; -} - xsapi_internal_string utils::get_query_from_params( _In_ const xsapi_internal_vector& params @@ -240,7 +93,7 @@ void utils::append_paging_info( // add maxItem parameter if (maxItems > 0) { - uriBuilder.append_query(_T("maxItems"), maxItems); + uriBuilder.append_query("maxItems", maxItems); } if (continuationToken.empty()) @@ -248,12 +101,12 @@ void utils::append_paging_info( // use skip items value if continuation token is empty if (skipItems > 0) { - uriBuilder.append_query(_T("skipItems"), skipItems); + uriBuilder.append_query("skipItems", skipItems); } } else { - uriBuilder.append_query(_T("continuationToken"), utils::string_t_from_internal_string(continuationToken)); + uriBuilder.append_query("continuationToken", continuationToken); } } @@ -976,7 +829,7 @@ utils::format_secure_device_address(String deviceAddress) // MPSD will base64 decode a non-valid SDA and the hashed value will be used // as the device token. The SDA can then be parsed by the title while // deserializing the MPSD session to retrieve the connectionAddress. - formattedDeviceAddress = _sdaPrefix.c_str() + deviceAddress; + formattedDeviceAddress = _sdaPrefix + deviceAddress; #endif Vector input(formattedDeviceAddress.c_str(), formattedDeviceAddress.c_str() + formattedDeviceAddress.size()); @@ -998,14 +851,14 @@ utils::parse_secure_device_address(String secureDeviceAddress) // a session host and the connection address which is used by the title // to connect to the title. - std::vector base64ConnectionAddress(xbox::services::convert::from_base64(utils::string_t_from_utf8(secureDeviceAddress.c_str()))); + std::vector base64ConnectionAddress(xbox::services::convert::from_base64(secureDeviceAddress.c_str())); auto formattedDeviceAddress = String(base64ConnectionAddress.begin(), base64ConnectionAddress.end()); String deviceAddress = formattedDeviceAddress; #if !(HC_PLATFORM == HC_PLATFORM_XDK || HC_PLATFORM == HC_PLATFORM_UWP) - if (deviceAddress.find(_sdaPrefix.c_str()) == 0) + if (deviceAddress.find(_sdaPrefix) == 0) { - deviceAddress = deviceAddress.substr(_sdaPrefix.length()); + deviceAddress = deviceAddress.substr(strlen(_sdaPrefix)); } #endif @@ -1045,7 +898,7 @@ utils::string_split( return vSubStrings; } -xsapi_internal_vector utils::string_split( +xsapi_internal_vector utils::string_split_internal( _In_ const xsapi_internal_string& string, _In_ xsapi_internal_string::value_type seperator ) @@ -1094,7 +947,7 @@ string_t utils::vector_join( return ss.str(); } -xsapi_internal_string utils::vector_join( +xsapi_internal_string utils::vector_join_internal( _In_ const std::vector& vector, _In_ xsapi_internal_string::value_type seperator ) @@ -1111,21 +964,6 @@ xsapi_internal_string utils::vector_join( return ss.str(); } -xsapi_internal_string utils::create_xboxlive_endpoint( - _In_ const xsapi_internal_string& subpath, - _In_ const std::shared_ptr& appConfig, - _In_ const xsapi_internal_string& protocol - ) -{ - UNREFERENCED_PARAMETER(appConfig); - xsapi_internal_stringstream source; - source << protocol; // eg. https or wss - source << "://"; - source << subpath; // eg. "achievements" - source << ".xboxlive.com"; - return source.str(); -} - string_t utils::replace_sub_string( _In_ const string_t& source, @@ -1154,11 +992,11 @@ utils::replace_sub_string( return result; } -string_t utils::read_file_to_string( - _In_ const string_t& filePath +xsapi_internal_string_t utils::read_file_to_string( + _In_ const xsapi_internal_string_t& filePath ) { - std::ifstream in(filePath, std::ios::in | std::ios::binary); + std::ifstream in(filePath.c_str(), std::ios::in | std::ios::binary); if (in) { std::vector fileData; @@ -1183,20 +1021,20 @@ string_t utils::read_file_to_string( static_cast(fileData[1]) == 0xBB && static_cast(fileData[2]) == 0xBF); // check for UTF-8 BOM - string_t fileDataString; + xsapi_internal_string_t fileDataString; #ifdef WIN32 // Convert file data to UTF16 string if (isUtf16LE) { uint32_t byteOrderMarkSizeInBytes = 2; uint32_t strLength = (fileSizeInBytes - byteOrderMarkSizeInBytes) / sizeof(WCHAR); - fileDataString = std::wstring(reinterpret_cast(fileData.data() + byteOrderMarkSizeInBytes), strLength); + fileDataString = xsapi_internal_string_t(reinterpret_cast(fileData.data() + byteOrderMarkSizeInBytes), strLength); } else { int byteOrderMarkSizeInBytes = (isUtf8) ? 3 : 0; uint32_t strLength = fileSizeInBytes - byteOrderMarkSizeInBytes; - std::string utf8FileData = std::string(fileData.data() + byteOrderMarkSizeInBytes, strLength); + xsapi_internal_string utf8FileData = xsapi_internal_string(fileData.data() + byteOrderMarkSizeInBytes, strLength); fileDataString = xbox::services::convert::utf8_to_utf16(utf8FileData); } #else @@ -1205,21 +1043,21 @@ string_t utils::read_file_to_string( { int byteOrderMarkSizeInBytes = 2; uint32_t strLength = (fileSizeInBytes - byteOrderMarkSizeInBytes) / sizeof(wchar_t); - string_t utf16FileData = string_t(fileData.data(), strLength); - fileDataString = utf16FileData = xbox::services::convert::to_string_t(utf16FileData); + xsapi_internal_string_t utf16FileData = xsapi_internal_string_t(fileData.data(), strLength); + fileDataString = utf16FileData; } else { int byteOrderMarkSizeInBytes = (isUtf8) ? 3 : 0; uint32_t strLength = fileSizeInBytes - byteOrderMarkSizeInBytes; - fileDataString = std::string(fileData.data(), strLength); + fileDataString = xsapi_internal_string(fileData.data(), strLength); } #endif return fileDataString; } } - return string_t(); + return xsapi_internal_string_t(); } int utils::interlocked_increment(volatile long& incrementNum) @@ -1295,6 +1133,25 @@ xsapi_internal_vector utils::uint32_array_to_internal_vector( return vector; } +bool utils::EnsureLessThanMaxLength(const char* str, size_t maxLength) +{ + size_t i = 0; + while (true) + { + if (i >= maxLength) + { + return false; + } + if (str[i] == '\0') + { + return true; + } + i++; + } + + return false; +} + String utils::ToLower(String str) noexcept { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) diff --git a/Source/Shared/xsapi_utils.h b/Source/Shared/xsapi_utils.h index 4d240936..54487dca 100644 --- a/Source/Shared/xsapi_utils.h +++ b/Source/Shared/xsapi_utils.h @@ -15,36 +15,6 @@ HC_DECLARE_TRACE_AREA(XSAPI); -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN - class xbox_live_services_settings; - class xbox_system_factory; -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_STAT_MANAGER_CPP_BEGIN - class stats_manager; -NAMESPACE_MICROSOFT_XBOX_SERVICES_STAT_MANAGER_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN - class NotificationService; -NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_BEGIN - class MultiplayerManager; -NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_BEGIN - class RealTimeActivityServiceFactory; -NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_END - -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN - class service_call_logging_config; - class service_call_logger_protocol; - class service_call_logger; - class logger; - class xsapi_telemetry; - class AppConfig; -NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END - NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN #ifndef __min @@ -60,90 +30,6 @@ inline bool operator<(const xbox::services::datetime& lhs, const xbox::services: return lhs.to_interval() < rhs.to_interval(); } -struct xsapi_singleton -{ - xsapi_singleton() = default; - ~xsapi_singleton(); - - HRESULT Initialize(_In_ const XblInitArgs* args); - - std::mutex m_rtaActivationCounterLock; - xsapi_internal_unordered_map m_rtaActiveSocketCountPerUser; - - std::mutex m_singletonLock; - std::mutex m_serviceSettingsLock; - std::mutex m_telemetryLock; - std::shared_ptr m_xboxServiceSettingsSingleton; - -#if HC_PLATFORM == HC_PLATFORM_XDK || XSAPI_UNIT_TESTS - std::mutex m_achievementServiceInitLock; - bool m_bHasAchievementServiceInitialized{ false }; - std::string m_eventProviderName; - GUID m_eventPlayerSessionId{}; -#endif - - // from Shared\xbox_live_app_config.cpp - std::shared_ptr m_appConfigSingleton; - - // from Misc\notification_service.cpp - std::shared_ptr m_notificationSingleton; - - // from Shared\service_call_logging_config.cpp - std::shared_ptr m_serviceLoggingConfigSingleton; - - // from Shared\xbox_live_app_config.cpp - std::mutex m_serviceLoggerProtocolSingletonLock; - std::shared_ptr m_serviceLoggerProtocolSingleton; - - // from Shared\utils_locales.cpp - xsapi_internal_string m_locales{ "en-US" }; - std::mutex m_locale_lock; - bool m_custom_locale_override{ false }; - - // from Shared\service_call_logger_data.cpp - uint32_t m_loggerId{ 0 }; - - // from Shared\service_call_logger.cpp - std::shared_ptr m_serviceLoggerSingleton; - - // from Services\RealTimeActivity\real_time_activity_service_factory.cpp - std::shared_ptr m_rtaFactoryInstance; - - // from Services\Presence\presence_service_internal.cpp - std::function m_onSetPresenceFinish; - - // from Shared\Logger\log.cpp - std::shared_ptr m_logger; - - // from Shared\xbox_system_factory.cpp - std::shared_ptr m_factoryInstance; - -#if XSAPI_DESKTOP_BRIDGE - // from System\user_impl_idp.cpp - uint64_t m_build = 0; - bool m_supportsGetTokenSilently; -#endif - -#if HC_PLATFORM == HC_PLATFORM_ANDROID - // TODO This is a temporary workaround for TCUI. XSAPI C++ TCUI API's accept a xal_user_handle, from which we extract - // XUID and privileges and call into Java code. Java code then calls back into XSAPI to make an HTTP call, but it does not pass and user - // context or xal_user_handle but it most likely should. Previously we just remembered the last signed in user, so we can - // emulate that behavior again for now. - std::atomic m_lastSignedInUser{ nullptr }; -#endif - - // from Shared\telemetry.cpp - std::shared_ptr m_telemetrySingleton; - - // from Services\Multiplayer\Manager\multiplayer_client_pending_request.cpp - String m_deviceId; - - XblApiType m_apiType{ XblApiType::XblCApi }; -}; - -std::shared_ptr get_xsapi_singleton(); -XTaskQueueHandle get_xsapi_singleton_async_queue(); - #ifndef _In_reads_bytes_ #define _In_reads_bytes_(s) #endif @@ -158,8 +44,6 @@ public: static xsapi_internal_string headers_to_string(_In_ const xsapi_internal_http_headers& headers); - static web::http::http_headers string_to_headers(_In_ const string_t& headers); - static xsapi_internal_string get_query_from_params(_In_ const xsapi_internal_vector& params); static xsapi_internal_string create_guid(_In_ bool removeBraces); @@ -244,12 +128,12 @@ public: static std::vector string_split( _In_ const string_t& string, _In_ string_t::value_type seperator - ); + ); - static xsapi_internal_vector string_split( + static xsapi_internal_vector string_split_internal( _In_ const xsapi_internal_string& string, _In_ xsapi_internal_string::value_type seperator - ); + ); static xbl_error_code convert_exception_to_xbox_live_error_code(); @@ -258,7 +142,7 @@ public: _In_ string_t::value_type seperator ); - static xsapi_internal_string vector_join( + static xsapi_internal_string vector_join_internal( _In_ const std::vector& vector, _In_ xsapi_internal_string::value_type seperator ); @@ -280,12 +164,6 @@ public: static HRESULT convert_http_status_to_hresult(_In_ uint32_t httpStatusCode); static xbl_error_code convert_http_status_to_xbox_live_error_code(_In_ uint32_t statusCode); - static xsapi_internal_string create_xboxlive_endpoint( - _In_ const xsapi_internal_string& subpath, - _In_ const std::shared_ptr& appConfig, - _In_ const xsapi_internal_string& protocol = "https" - ); - #if HC_PLATFORM_IS_MICROSOFT static xsapi_internal_string internal_string_from_utf16(_In_z_ const wchar_t* utf16); #endif @@ -306,110 +184,9 @@ public: static int utf8_from_char_t(_In_z_ const char_t* inArray, _Out_writes_z_(cchOutArray) char* outArray, _In_ int cchOutArray); static int char_t_from_utf8(_In_z_ const char* inArray, _Out_writes_z_(cchOutArray) char_t* outArray, _In_ int cchOutArray); - static void generate_locales(); - static xsapi_internal_string get_locales(); - - static void set_locales(_In_ const xsapi_internal_string& locale); - -#if !XSAPI_NO_PPL - - template - static pplx::task > create_exception_free_task( - _In_ const pplx::task >& t - ) - { - return t.then([](pplx::task > result) - { - try - { - return result.get(); - } - catch (const std::exception& e) - { - xbl_error_code err = xbox::services::utils::convert_exception_to_xbox_live_error_code(); - return xbl_result(err, e.what()); - } -#ifdef __cplusplus_winrt - catch (Platform::Exception^ e) - { - xbl_error_code errc = static_cast(e->HResult); - return xbl_result(errc, xbox::services::convert::to_utf8string(e->Message->Data())); - } -#endif - }); - } -#endif // !XSAPI_NO_PPL - - static xsapi_internal_vector internal_string_vector_from_std_string_vector( - _In_ const std::vector& stdVector - ) - { - auto size = stdVector.size(); - xsapi_internal_vector internalVector(size); - for (size_t i = 0; i < size; ++i) - { - internalVector[i] = utils::internal_string_from_string_t(stdVector[i]); - } - return internalVector; - } - - static xsapi_internal_vector internal_string_vector_from_utf8_array( - _In_ const char** utf8array, - _In_ uint32_t arraySize - ) - { - xsapi_internal_vector internalVector(arraySize); - for (uint32_t i = 0; i < arraySize; ++i) - { - internalVector[i] = utf8array[i]; - } - return internalVector; - } - - static std::vector std_string_vector_from_internal_string_vector( - _In_ const xsapi_internal_vector& internalVector - ) - { - auto size = internalVector.size(); - std::vector vector(size); - for (size_t i = 0; i < size; ++i) - { - vector[i] = utils::string_t_from_internal_string(internalVector[i]); - } - return vector; - } - - template - static std::vector std_vector_from_internal_vector( - _In_ const xsapi_internal_vector& internalVector - ) - { - return std::vector(internalVector.begin(), internalVector.end()); - } - - template - static std::vector std_vector_external_from_internal_vector( - _In_ const xsapi_internal_vector& internalVector - ) - { - return std::vector(internalVector.begin(), internalVector.end()); - } - - template - static xsapi_internal_vector internal_vector_from_std_vector( - _In_ const std::vector& vector - ) - { - return xsapi_internal_vector(vector.begin(), vector.end()); - } - - template - static xsapi_internal_vector internal_vector_from_std_vector( - _In_ const std::vector& vector - ) - { - return xsapi_internal_vector(vector.begin(), vector.end()); - } + static String generate_locales(); + // Helper function to get locales from GlobalState. Fallback to "en-us" if GlobalState is not initialized + static String get_locales(); static string_t replace_sub_string( _In_ const string_t& source, @@ -417,8 +194,8 @@ public: _In_ const string_t& replacement ); - static string_t read_file_to_string( - _In_ const string_t& filePath + static xsapi_internal_string_t read_file_to_string( + _In_ const xsapi_internal_string_t& filePath ); inline static uint32_t string_t_to_uint32( @@ -556,6 +333,8 @@ public: size_t intArrayCount ); + static bool EnsureLessThanMaxLength(const char* str, size_t maxLength); + // date and time constants static constexpr uint64_t TICKS_PER_MS = 10000; static constexpr uint64_t TICKS_PER_SEC = (1000 * TICKS_PER_MS); @@ -631,9 +410,9 @@ public: static time_t time_t_from_datetime(const xbox::services::datetime& datetime); // Creates an asyncBlock that clean itself up in the completion callback - static XAsyncBlock* MakeDefaultAsyncBlock(XTaskQueueHandle queue = get_xsapi_singleton_async_queue()); + static XAsyncBlock* MakeDefaultAsyncBlock(XTaskQueueHandle queue); - static XAsyncBlock* MakeAsyncBlock(XTaskQueueHandle queue = get_xsapi_singleton_async_queue(), void* context = nullptr, XAsyncCompletionRoutine* callback = nullptr); + static XAsyncBlock* MakeAsyncBlock(XTaskQueueHandle queue, void* context, XAsyncCompletionRoutine* callback); private: static xsapi_internal_vector get_locale_list(); @@ -643,55 +422,4 @@ private: utils& operator=(const utils&); }; -template -class bimap -{ -public: - typename xsapi_internal_unordered_map::iterator find(const K& key) - { - return m_map.find(key); - } - - typename xsapi_internal_unordered_map::iterator begin() - { - return m_map.begin(); - } - - typename xsapi_internal_unordered_map::iterator end() - { - return m_map.end(); - } - - typename xsapi_internal_unordered_map::iterator reverse_find(const V& value) - { - return m_reverseMap.find(value); - } - - typename xsapi_internal_unordered_map::iterator reverse_begin() - { - return m_reverseMap.begin(); - } - - typename xsapi_internal_unordered_map::iterator reverse_end() - { - return m_reverseMap.end(); - } - - void insert(const K& key, const V& value) - { - m_map[key] = value; - m_reverseMap[value] = key; - } - - void erase(typename xsapi_internal_unordered_map::iterator iterator) - { - m_reverseMap.erase(iterator->second); - m_map.erase(iterator); - } - -private: - xsapi_internal_unordered_map m_map; - xsapi_internal_unordered_map m_reverseMap; -}; - NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END diff --git a/Source/System/a/java_interop.cpp b/Source/System/a/java_interop.cpp index 7b6fac5a..c10f8748 100644 --- a/Source/System/a/java_interop.cpp +++ b/Source/System/a/java_interop.cpp @@ -6,7 +6,6 @@ #include "a/jni_utils.h" #include "a/java_interop.h" #include "TCUI/Android/title_callable_ui_jni.h" -#include "xbox_system_factory.h" using namespace xbox::services::system; @@ -174,7 +173,6 @@ xbl_result java_interop::finish_initialization(JNIEnv* env, jobject clsLoa if (http_call_register_natives(env, clsLoader, loadClass) && xbox_live_app_config_register_natives(env, clsLoader, loadClass) && (!useTcui || title_callable_ui_register_natives(env, clsLoader, loadClass)) - && xsapi_telemetry::register_natives(env, clsLoader, loadClass) ) { m_initialized = true; @@ -452,4 +450,22 @@ String java_interop::StringFromJString(JNIEnv* env, jstring jStr) return string; } +void java_interop::StoreUser(User&& user) +{ + std::lock_guard lock{ m_storedUserMutex }; + m_storedUser = std::make_shared(std::move(user)); +} + +std::shared_ptr java_interop::GetStoredUser() +{ + std::lock_guard lock{ m_storedUserMutex }; + return m_storedUser; +} + +std::shared_ptr java_interop::ExtractStoredUser() +{ + std::lock_guard lock{ m_storedUserMutex }; + return std::move(m_storedUser); +} + NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END \ No newline at end of file diff --git a/Source/System/a/java_interop.h b/Source/System/a/java_interop.h index fbb2f122..e4bd0f05 100644 --- a/Source/System/a/java_interop.h +++ b/Source/System/a/java_interop.h @@ -57,6 +57,14 @@ public: jclass GetLocalStorageClass() const { return m_localStorageClass; } + // TODO This is a temporary workaround for TCUI. XSAPI C++ TCUI API's accept a xal_user_handle, from which we extract + // XUID and privileges and call into Java code. Java code then calls back into XSAPI to make an HTTP call, but it does not pass and user + // context or xal_user_handle but it most likely should. Previously we just remembered the last signed in user, so we can + // emulate that behavior again for now. + void StoreUser(User&& user); + std::shared_ptr GetStoredUser(); + std::shared_ptr ExtractStoredUser(); + private: JavaVM* m_javaVM; @@ -75,6 +83,9 @@ private: std::mutex m_localStoragePathLock; xbl_result finish_initialization(JNIEnv* env, jobject clsLoader, jmethodID loadClass, bool useTcui); + + std::shared_ptr m_storedUser{ nullptr }; + std::mutex m_storedUserMutex; }; }} \ No newline at end of file diff --git a/Source/System/auth_config.cpp b/Source/System/auth_config.cpp deleted file mode 100644 index 82023f5d..00000000 --- a/Source/System/auth_config.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pch.h" -#include "shared_macros.h" -#include "xsapi_utils.h" -#include "auth_config.h" - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN - - -xsapi_internal_string get_endpoint_path( - _In_ const xsapi_internal_string& serviceName, - _In_ const xsapi_internal_string& environmentPrefix, - _In_ const xsapi_internal_string& environment, - _In_ bool appendProtocol = true - ) -{ - xsapi_internal_stringstream source; - if (appendProtocol) - { - source << "https://"; - } - source << environmentPrefix; - source << serviceName; - source << environment; - source << ".xboxlive.com"; - return source.str(); -} - -auth_config::auth_config() : - m_useCompactTicket(false), - m_detailError(0), - m_httpStatusCode(0) -{ - m_xtokenComposition = { token_identity_type::u_token, token_identity_type::d_token, token_identity_type::t_token }; -} - -auth_config::auth_config( - _In_ xsapi_internal_string sandbox, - _In_ xsapi_internal_string environmentPrefix, - _In_ xsapi_internal_string environment, - _In_ bool useCompactTicket, - _In_ bool isCreatorsTitle, - _In_ xsapi_internal_string scope) : - m_useCompactTicket(useCompactTicket), - m_sandbox(std::move(sandbox)), - m_detailError(0), - m_rpsTicketPolicy(useCompactTicket? "MBI_SSL" : "DELEGATION"), - m_xboxLiveRelyingParty("http://auth.xboxlive.com"), - m_xboxLiveEndpoint("https://xboxlive.com"), - m_environment(std::move(environment)) -{ - m_xTitleEndpoint = get_endpoint_path("title.mgt", environmentPrefix, environment); - m_deviceTokenEndpoint = get_endpoint_path("device.auth", environmentPrefix, environment); - m_titleTokenEndpoint = get_endpoint_path("title.auth", environmentPrefix, environment); - m_userTokenEndpoint = get_endpoint_path("user.auth", environmentPrefix, environment); - m_serviceTokenEndpoint = get_endpoint_path("service.auth", environmentPrefix, environment); - m_xTokenEndpoint = get_endpoint_path("xsts.auth", environmentPrefix, environment); - m_userTokenSiteName = get_endpoint_path("open-user.auth", "", environment, false); - m_rpsTicketService = isCreatorsTitle ? scope : (useCompactTicket ? m_userTokenSiteName : scope); - m_xtokenComposition = { token_identity_type::u_token, token_identity_type::d_token, token_identity_type::t_token }; -} - -const xsapi_internal_string& auth_config::rps_ticket_service() const -{ - std::lock_guard lock(m_mutex); - return m_rpsTicketService; -} - -void auth_config::set_rps_ticket_service( - _In_ xsapi_internal_string value - ) -{ - std::lock_guard lock(m_mutex); - m_rpsTicketService = std::move(value); -} - -const xsapi_internal_string& auth_config::rps_ticket_policy() const -{ - std::lock_guard lock(m_mutex); - return m_rpsTicketPolicy; -} - -void auth_config::set_rps_ticket_policy( - _In_ xsapi_internal_string value - ) -{ - std::lock_guard lock(m_mutex); - m_rpsTicketPolicy = std::move(value); -} - -const xsapi_internal_string& auth_config::xbox_live_endpoint() const -{ - std::lock_guard lock(m_mutex); - return m_xboxLiveEndpoint; -} - -void auth_config::set_xbox_live_endpoint( - _In_ xsapi_internal_string value -) -{ - std::lock_guard lock(m_mutex); - m_xboxLiveEndpoint = std::move(value); -} - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END diff --git a/Source/System/auth_config.h b/Source/System/auth_config.h deleted file mode 100644 index 9238dd71..00000000 --- a/Source/System/auth_config.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -// TODO: remove most of this now that XAL handles it -#pragma once -#include -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN - -enum class token_identity_type -{ - x_token = 0, - d_token, - t_token, - u_token, - s_token, -}; - - -class auth_config -{ -public: - /// - /// Internal function - /// - auth_config(); - - /// - /// Internal function - /// - auth_config( - _In_ xsapi_internal_string sandbox, - _In_ xsapi_internal_string environmentPrefix, - _In_ xsapi_internal_string environment, - _In_ bool useCompactTicket, - _In_ bool isCreatorsTitle, - _In_ xsapi_internal_string scope - ); - - const xsapi_internal_string& xbox_live_endpoint() const; - void set_xbox_live_endpoint(_In_ xsapi_internal_string value); - - const xsapi_internal_string& rps_ticket_service() const; - void set_rps_ticket_service(_In_ xsapi_internal_string value); - const xsapi_internal_string& rps_ticket_policy() const; - void set_rps_ticket_policy(_In_ xsapi_internal_string value); - -#if !HC_PLATFORM_IS_MICROSOFT - /// - /// Internal function - /// - bool use_win10_auth() const; - bool use_compact_ticket() const; - - void set_app_id(xsapi_internal_string appId); - const xsapi_internal_string& app_id() const; - void set_microsoft_account_id(xsapi_internal_string accountId); - const xsapi_internal_string& microsoft_account_id() const; - - void set_detail_error(uint32_t detail_error); - uint32_t detail_error() const; - - const xsapi_internal_string& device_token_endpoint() const; - void set_device_token_endpoint(_In_ xsapi_internal_string value); - const xsapi_internal_string& title_token_endpoint() const; - void set_title_token_endpoint(_In_ xsapi_internal_string value); - const xsapi_internal_string& service_token_endpoint() const; - void set_service_token_endpoint(_In_ xsapi_internal_string value); - - const xsapi_internal_string& user_token_site_name() const; - void set_user_token_site_name(_In_ xsapi_internal_string value); - const xsapi_internal_string& user_token_endpoint() const; - void set_user_token_endpoint(_In_ xsapi_internal_string value); - - const xsapi_internal_string& xbox_live_relying_party() const; - void set_xbox_live_relying_party(_In_ xsapi_internal_string value); - const xsapi_internal_string& x_token_endpoint() const; - void set_x_token_endpoint(_In_ xsapi_internal_string value); - const xsapi_internal_string& x_title_endpoint() const; - void set_x_title_endpoint(_In_ xsapi_internal_string value); - - const xsapi_internal_string& redirect() const; - void set_redirect(_In_ xsapi_internal_string value); - - const xsapi_internal_vector& xtoken_composition() const; - void set_xtoken_composition(xsapi_internal_vector value); - - uint32_t http_status_code() const; - void set_http_status_code(_In_ uint32_t httpStatusCode); - - const xsapi_internal_string& Environment() const; - -#endif - - // reset the variables could change in each token fetching. - void reset(); - -private: - mutable std::mutex m_mutex; - xsapi_internal_string m_sandbox; - xsapi_internal_string m_rpsTicketService; - xsapi_internal_string m_rpsTicketPolicy; - xsapi_internal_string m_xTitleEndpoint; - xsapi_internal_string m_deviceTokenEndpoint; - xsapi_internal_string m_titleTokenEndpoint; - xsapi_internal_string m_userTokenEndpoint; - xsapi_internal_string m_serviceTokenEndpoint; - xsapi_internal_string m_xTokenEndpoint; - xsapi_internal_string m_userTokenSiteName; - xsapi_internal_string m_xboxLiveRelyingParty; - xsapi_internal_string m_xboxLiveEndpoint; - xsapi_internal_string m_appId; - xsapi_internal_string m_accountId; - bool m_useCompactTicket; - uint32_t m_detailError; - xsapi_internal_string m_redirect; - xsapi_internal_vector m_xtokenComposition; - uint32_t m_httpStatusCode; - xsapi_internal_string m_environment; -}; - - -NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END diff --git a/Source/System/iOS/xbox_live_app_config_ios.mm b/Source/System/iOS/xbox_live_app_config_ios.mm index 7b36aa5e..cf426da1 100644 --- a/Source/System/iOS/xbox_live_app_config_ios.mm +++ b/Source/System/iOS/xbox_live_app_config_ios.mm @@ -5,6 +5,8 @@ #include "xsapi-cpp/system.h" #include "xbox_live_app_config_internal.h" #import "XBLiOSGlobalState.h" +#include +#include "uri_impl.h" using namespace xbox::services; diff --git a/Source/System/ppltasks_extra.h b/Source/System/ppltasks_extra.h deleted file mode 100644 index 4798f0c8..00000000 --- a/Source/System/ppltasks_extra.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) Microsoft Corporation -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma once -#if !XSAPI_NO_PPL - -#include -#include -#include -#include - -namespace Concurrency -{ - namespace extras - { - namespace details - { - static void iterative_task_impl(concurrency::task_completion_event finished, std::function()> body, concurrency::cancellation_token ct) - { - body().then([=](concurrency::task previous) { - try { - if (previous.get()) - iterative_task_impl(finished, body, ct); - else - finished.set(); - } - catch (...) { - finished.set_exception(std::current_exception()); - } - }, ct); - } - } // namespace details - - - /// - /// Creates a task from given user Functor, which will be scheduled after million senconds. - /// - /// - /// The type of the user task Functor. - /// - /// - /// The delay before starting the task. - /// - /// - /// The user task Functor. - /// - /// - /// The optional cancellation token, which will be passed to the return task. - /// - /// - /// It will return a task constructed with user Functor , and cancellation token . - /// The returning task will be scheduled after million seconds. - /// - /// - /**/ - template - auto create_delayed_task(std::chrono::milliseconds delay, Func func, concurrency::cancellation_token token = concurrency::cancellation_token::none()) -> decltype(create_task(func)) - { - concurrency::task_completion_event tce; - - auto pTimer = new concurrency::timer(static_cast(delay.count()), 0, NULL, false); - auto pCallback = new concurrency::call([tce](int) { - tce.set(); - }); - - pTimer->link_target(pCallback); - pTimer->start(); - - return create_task(tce).then([pCallback, pTimer]() { - delete pCallback; - delete pTimer; - }).then(func, token); - } - - /// - /// Creates a task iteratively execute user Functor. During the process, each new iteration will be the continuation of the - /// last iteration's returning task, and the process will keep going on until the Boolean value from returning task becomes False. - /// - /// - /// The user Functor used as loop body. It is required to return a task with type bool, which used as predictor that decides - /// whether the loop needs to be continued. - /// - /// - /// The cancellation token linked to the iterative task. - /// - /// - /// The task that will perform the asynchronous iterative execution. - /// - /// - /// This function dynamically creates a long chain of continuations by iteratively concating tasks created by user Functor , - /// The iteration will not stop until the result of the returning task from user Functor is False . - /// - /**/ - inline task create_iterative_task(std::function()> body, cancellation_token ct = cancellation_token::none()) - { - concurrency::task_completion_event finished; - create_task([=] { - try { - details::iterative_task_impl(finished, body, ct); - } - catch (...) { - finished.set_exception(std::current_exception()); - } - }, ct); - return create_task(finished, ct); - } - - } -} - - -#endif \ No newline at end of file diff --git a/Tests/ApiExplorer/APIExplorer.Shared.vcxitems b/Tests/ApiExplorer/APIExplorer.Shared.vcxitems index b2bd1375..58ac1317 100644 --- a/Tests/ApiExplorer/APIExplorer.Shared.vcxitems +++ b/Tests/ApiExplorer/APIExplorer.Shared.vcxitems @@ -182,6 +182,7 @@ NotUsing + @@ -215,6 +216,7 @@ + NotUsing @@ -511,6 +513,9 @@ true + + + true true diff --git a/Tests/ApiExplorer/APIExplorer.Shared.vcxitems.filters b/Tests/ApiExplorer/APIExplorer.Shared.vcxitems.filters index d6334b87..87d385d2 100644 --- a/Tests/ApiExplorer/APIExplorer.Shared.vcxitems.filters +++ b/Tests/ApiExplorer/APIExplorer.Shared.vcxitems.filters @@ -253,6 +253,9 @@ APIs + + Shared + @@ -446,6 +449,9 @@ Shared + + Shared + @@ -780,5 +786,8 @@ Tests\multiplayerManager + + Tests\titleStorage + \ No newline at end of file diff --git a/Tests/ApiExplorer/APIs/apis.cpp b/Tests/ApiExplorer/APIs/apis.cpp index c34d2089..e895ea68 100644 --- a/Tests/ApiExplorer/APIs/apis.cpp +++ b/Tests/ApiExplorer/APIs/apis.cpp @@ -8,6 +8,12 @@ int SetCheckHR_Lua(lua_State *L) return 0; } +int GetCheckHR_Lua(lua_State *L) +{ + lua_pushboolean(L, Data()->m_checkHR); + return 1; +} + int Sleep_Lua(lua_State *L) { DWORD time = (DWORD)GetUint32FromLua(L, 1, 0); @@ -188,6 +194,34 @@ int MultiDeviceGetRemoteXuid_Lua(lua_State *L) return 1; } +int APIRunner_AssertOnAllocOfId_Lua(lua_State *L) +{ + auto id = GetUint64FromLua(L, 1, 0); + auto memHook = GetApiRunnerMemHook(); + memHook->AssertOnAllocOfId(id); + return LuaReturnHR(L, S_OK); +} + +int APIRunner_MemStartTracking_Lua(lua_State *L) +{ + auto memHook = GetApiRunnerMemHook(); + memHook->StartMemTracking(); + return LuaReturnHR(L, S_OK); +} + +int APIRunner_LogStats_Lua(lua_State *L) +{ + auto memHook = GetApiRunnerMemHook(); + memHook->LogStats("MemCheck"); + return LuaReturnHR(L, S_OK); +} + +int APIRunner_MemLogUnhookedStats_Lua(lua_State *L) +{ + auto memHook = GetApiRunnerMemHook(); + memHook->LogUnhookedStats(); + return LuaReturnHR(L, S_OK); +} void RegisterLuaAPIs() { @@ -239,6 +273,7 @@ void RegisterLuaAPIs() SetupAPIs_GRTS(); lua_register(Data()->L, "SetCheckHR", SetCheckHR_Lua); + lua_register(Data()->L, "GetCheckHR", GetCheckHR_Lua); lua_register(Data()->L, "StopTestFile", StopTestFile_Lua); lua_register(Data()->L, "Sleep", Sleep_Lua); lua_register(Data()->L, "LogToScreen", LogToScreen_Lua); @@ -256,6 +291,11 @@ void RegisterLuaAPIs() lua_register(Data()->L, "MultiDeviceIsHost", MultiDeviceIsHost_Lua); lua_register(Data()->L, "MultiDeviceGetRemoteXuid", MultiDeviceGetRemoteXuid_Lua); lua_register(Data()->L, "MultiDeviceWaitTillRemoteState", MultiDeviceWaitTillRemoteState_Lua); + + lua_register(Data()->L, "APIRunner_MemStartTracking", APIRunner_MemStartTracking_Lua); + lua_register(Data()->L, "APIRunner_LogStats", APIRunner_LogStats_Lua); + lua_register(Data()->L, "APIRunner_AssertOnAllocOfId", APIRunner_AssertOnAllocOfId_Lua); + lua_register(Data()->L, "APIRunner_MemLogUnhookedStats", APIRunner_MemLogUnhookedStats_Lua); } void SetupAPIS_Platform() diff --git a/Tests/ApiExplorer/APIs/apis_cpp_multiplayer.cpp b/Tests/ApiExplorer/APIs/apis_cpp_multiplayer.cpp index ab31c1e2..9e5f63a8 100644 --- a/Tests/ApiExplorer/APIs/apis_cpp_multiplayer.cpp +++ b/Tests/ApiExplorer/APIs/apis_cpp_multiplayer.cpp @@ -2,6 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" +using namespace utility; + #if CPP_TESTS_ENABLED struct MultiplayerStateCpp { @@ -27,7 +29,7 @@ struct MultiplayerStateCpp static uint64_t runId{ largeInt.QuadPart }; #else - static uint64_t runId{ utility::datetime::utc_now().to_interval() }; + static uint64_t runId{ datetime::utc_now().to_interval() }; #endif std::stringstream ss; @@ -179,7 +181,7 @@ int MultiplayerSessionTimeOfSessionCpp_Lua(lua_State *L) { auto sessionHandle = GetSessionHandleFromArgCpp(L, 1); - utility::datetime timeOfSession = sessionHandle->date_of_session(); + datetime timeOfSession = sessionHandle->date_of_session(); LogToFile("MultiplayerSessionStartTime timeOfSession:%s", xbox::services::Utils::StringFromStringT(timeOfSession.to_string()).c_str()); return LuaReturnHR(L, S_OK); @@ -190,7 +192,7 @@ int MultiplayerSessionGetInitializationInfoCpp_Lua(lua_State *L) auto sessionHandle = GetSessionHandleFromArgCpp(L, 1); xbox::services::multiplayer::multiplayer_initialization_stage stage = sessionHandle->initialization_stage(); - utility::datetime stageStartTime = sessionHandle->initializing_stage_start_time(); + datetime stageStartTime = sessionHandle->initializing_stage_start_time(); uint32_t episode = sessionHandle->intializing_episode(); LogToFile("MultiplayerSessionGetInitializationInfoCpp"); @@ -1532,6 +1534,11 @@ int MultiplayerSearchHandleDetailsSessionOwnerXuids_Lua(lua_State *L) int MultiplayerSearchHandleDetailsTags_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + std::vector tags = MPStateCpp()->searchHandleDetails->tags(); LogToFile("MultiplayerSearchHandleDetailsTags"); @@ -1546,6 +1553,11 @@ int MultiplayerSearchHandleDetailsTags_Lua(lua_State *L) int MultiplayerSearchHandleDetailsStringsMetadata_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + auto stringsMetadata = MPStateCpp()->searchHandleDetails->strings_metadata(); LogToFile("MultiplayerSearchHandleDetailsStringsMetadata"); @@ -1560,6 +1572,11 @@ int MultiplayerSearchHandleDetailsStringsMetadata_Lua(lua_State *L) int MultiplayerSearchHandleDetailsNumbersMetadata_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + auto numbersMetadata = MPStateCpp()->searchHandleDetails->numbers_metadata(); LogToFile("MultiplayerSearchHandleDetailsNumbersMetadata"); @@ -1574,6 +1591,11 @@ int MultiplayerSearchHandleDetailsNumbersMetadata_Lua(lua_State *L) int MultiplayerSearchHandleDetailsVisibility_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + xbox::services::multiplayer::multiplayer_session_visibility sessionVisibility = MPStateCpp()->searchHandleDetails->visibility(); LogToFile("MultiplayerSearchHandleDetailsVisibility: visibility=%u", sessionVisibility); @@ -1582,6 +1604,11 @@ int MultiplayerSearchHandleDetailsVisibility_Lua(lua_State *L) int MultiplayerSearchHandleDetailsJoinRestriction_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + xbox::services::multiplayer::multiplayer_session_restriction joinRestriction = MPStateCpp()->searchHandleDetails->join_restriction(); LogToFile("MultiplayerSearchHandleDetailsJoinRestriction: restriction=%u", joinRestriction); @@ -1590,6 +1617,11 @@ int MultiplayerSearchHandleDetailsJoinRestriction_Lua(lua_State *L) int MultiplayerSearchHandleDetailsClosed_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + bool sessionClosed = MPStateCpp()->searchHandleDetails->closed(); LogToFile("MultiplayerSearchHandleDetailsClosed: closed=%d", sessionClosed); @@ -1598,6 +1630,11 @@ int MultiplayerSearchHandleDetailsClosed_Lua(lua_State *L) int MultiplayerSearchHandleDetailsMemberCounts_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + uint32_t membersCount = MPStateCpp()->searchHandleDetails->members_count(); uint32_t maxMembersCount = MPStateCpp()->searchHandleDetails->max_members_count(); @@ -1607,6 +1644,11 @@ int MultiplayerSearchHandleDetailsMemberCounts_Lua(lua_State *L) int MultiplayerSearchHandleDetailsHandleCreationTime_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + auto creationTime = MPStateCpp()->searchHandleDetails->handle_creation_time(); LogToFile("MultiplayerSearchHandleDetailsHandleCreationTime: creation time=%s", xbox::services::Utils::StringFromStringT(creationTime.to_string()).c_str()); @@ -1615,6 +1657,11 @@ int MultiplayerSearchHandleDetailsHandleCreationTime_Lua(lua_State *L) int MultiplayerSearchHandleDetailsCustomSessionPropertiesJson_Lua(lua_State *L) { + if (MPStateCpp()->searchHandleDetails == nullptr) + { + return LuaReturnHR(L, S_OK); + } + string_t customPropertiesJsonStr = MPStateCpp()->searchHandleDetails->custom_session_properties_json().serialize(); LogToFile("MultiplayerSearchHandleDetailsCustomSessionPropertiesJson: properties=%s", xbox::services::Utils::StringFromStringT(customPropertiesJsonStr).c_str()); @@ -1672,6 +1719,11 @@ int MatchmakingServiceGetMatchTicketDetails_Lua(lua_State* L) ticketId = Data()->matchTicketResponseCpp.match_ticket_id(); } + if (Data()->xalUser == nullptr) + { + return LuaReturnHR(L, E_UNEXPECTED); + } + std::shared_ptr xblc = std::make_shared(Data()->xboxLiveContext); xblc->matchmaking_service().get_match_ticket_details( serviceConfigurationId, diff --git a/Tests/ApiExplorer/APIs/apis_cpp_privacy.cpp b/Tests/ApiExplorer/APIs/apis_cpp_privacy.cpp index 37d46dd7..964f057d 100644 --- a/Tests/ApiExplorer/APIs/apis_cpp_privacy.cpp +++ b/Tests/ApiExplorer/APIs/apis_cpp_privacy.cpp @@ -39,8 +39,10 @@ string_t ConvertXblPermissionToStringT(XblPermission permissionType) return xbox::services::privacy::permission_id_constants::view_target_video_history(); case XblPermission::ViewTargetVideoStatus: return xbox::services::privacy::permission_id_constants::view_target_video_status(); - //case XblPermission::WriteComment: - //unsupported + case XblPermission::WriteComment: + case XblPermission::ShareItem: + case XblPermission::ShareTargetContentToExternalNetworks: + case XblPermission::Unknown: default: return _T("Unknown"); } diff --git a/Tests/ApiExplorer/APIs/apis_cpp_social_manager.cpp b/Tests/ApiExplorer/APIs/apis_cpp_social_manager.cpp index 02d8956b..1516cceb 100644 --- a/Tests/ApiExplorer/APIs/apis_cpp_social_manager.cpp +++ b/Tests/ApiExplorer/APIs/apis_cpp_social_manager.cpp @@ -77,6 +77,10 @@ HRESULT SocialManagerDoWorkCpp() LogToFile("social_manager::do_work: local_user_added event"); CallLuaFunctionWithHr(S_OK, "OnSocialManagerDoWorkCpp_LocalUserAddedEvent"); break; + case xbox::services::social::manager::social_event_type::local_user_removed: + LogToFile("social_manager::do_work: local_user_removed event"); + CallLuaFunctionWithHr(S_OK, "OnSocialManagerDoWorkCpp_LocalUserRemovedEvent"); + break; case xbox::services::social::manager::social_event_type::social_user_group_loaded: LogToFile("social_manager::do_work: social_user_group_loaded event"); CallLuaFunctionWithHr(S_OK, "OnSocialManagerDoWorkCpp_SocialUserGroupLoadedEvent"); diff --git a/Tests/ApiExplorer/APIs/apis_cpp_title_storage.cpp b/Tests/ApiExplorer/APIs/apis_cpp_title_storage.cpp index ce6a453a..e1462078 100644 --- a/Tests/ApiExplorer/APIs/apis_cpp_title_storage.cpp +++ b/Tests/ApiExplorer/APIs/apis_cpp_title_storage.cpp @@ -233,7 +233,7 @@ int TitleStorageServiceUploadBlob_Lua(lua_State* L) char zero = '0'; for (size_t i = 0; i < blobBufferSize; i++) { - (*blobBuffer)[i] = (char)(zero + i % 10); + (*blobBuffer)[i] = static_cast(zero + i % 10); } std::shared_ptr xblc = std::make_shared(Data()->xalUser); diff --git a/Tests/ApiExplorer/APIs/apis_docs.cpp b/Tests/ApiExplorer/APIs/apis_docs.cpp index b4e05139..76862c94 100644 --- a/Tests/ApiExplorer/APIs/apis_docs.cpp +++ b/Tests/ApiExplorer/APIs/apis_docs.cpp @@ -123,6 +123,49 @@ void CodeSnippets() UNREFERENCED_PARAMETER(statisticChangedFunctionContext); UNREFERENCED_PARAMETER(hr); } + + { + // CODE SNIPPET START: DocsAddConnectionIdChangedHandler + void* context{ nullptr }; + XblFunctionContext connectionIdChangedFunctionContext = XblMultiplayerAddConnectionIdChangedHandler( + xblContextHandle, + [](void* context) { + UNREFERENCED_PARAMETER(context); // CODE SNIP SKIP + XTaskQueueHandle queue{ nullptr }; // CODE SNIP SKIP + auto xblContextHandle = Data()->xboxLiveContext; // CODE SNIP SKIP + XblMultiplayerSessionHandle sessionHandle; // Retrieve the MPSD session to update + sessionHandle = nullptr; // CODE SNIP SKIP + XblMultiplayerSessionCurrentUserSetStatus(sessionHandle, XblMultiplayerSessionMemberStatus::Active); + + auto asyncBlock = std::make_unique(); + asyncBlock->queue = queue; + asyncBlock->context = nullptr; + asyncBlock->callback = [](XAsyncBlock* asyncBlock) + { + std::unique_ptr asyncBlockPtr{ asyncBlock }; + + XblMultiplayerSessionHandle sessionHandle; + HRESULT hr = XblMultiplayerWriteSessionResult(asyncBlock, &sessionHandle); + if (SUCCEEDED(hr)) + { + // If the write call succeeds, the connection id has been updated and no further action is needed. + } + else + { + // If the write call fails, it is likely the user has been removed from the session. + } + }; + + auto hr = XblMultiplayerWriteSessionAsync(xblContextHandle, sessionHandle, XblMultiplayerSessionWriteMode::UpdateExisting, asyncBlock.get()); + if (SUCCEEDED(hr)) + { + asyncBlock.release(); + } + }, + context); + // CODE SNIPPET END + UNREFERENCED_PARAMETER(connectionIdChangedFunctionContext); + } } } diff --git a/Tests/ApiExplorer/APIs/apis_libhttp.cpp b/Tests/ApiExplorer/APIs/apis_libhttp.cpp index eeb599d6..eb9fa375 100644 --- a/Tests/ApiExplorer/APIs/apis_libhttp.cpp +++ b/Tests/ApiExplorer/APIs/apis_libhttp.cpp @@ -305,7 +305,7 @@ int HCHttpCallResponseGetHeaderAtIndex_Lua(lua_State *L) return LuaReturnHR(L, hr); } -void CALLBACK WebsocketMessageReceived( +void CALLBACK ExampleWebsocketMessageReceived( _In_ HCWebsocketHandle websocket, _In_z_ const char* incomingBodyString, _In_ void* functionContext @@ -317,7 +317,7 @@ void CALLBACK WebsocketMessageReceived( CallLuaFunction("OnHCWebsocketMessageReceived"); } -void CALLBACK WebsocketClosed( +void CALLBACK ExampleWebsocketClosed( _In_ HCWebsocketHandle websocket, _In_ HCWebSocketCloseStatus closeStatus, _In_ void* functionContext @@ -333,7 +333,7 @@ int HCWebSocketCreate_Lua(lua_State *L) { // CODE SNIPPET START: HCWebSocketCreate HCWebsocketHandle websocket = nullptr; - HRESULT hr = HCWebSocketCreate(&websocket, WebsocketMessageReceived, nullptr, WebsocketClosed, nullptr); + HRESULT hr = HCWebSocketCreate(&websocket, ExampleWebsocketMessageReceived, nullptr, ExampleWebsocketClosed, nullptr); // CODE SNIPPET END Data()->websocket = websocket; @@ -460,6 +460,7 @@ int HCTraceSetTraceToDebugger_Lua(lua_State *L) { // CODE SNIPPET START: HCTraceSetTraceToDebugger HCSettingsSetTraceLevel(HCTraceLevel::Verbose); // See HCTraceLevel enum for various levels + // TODO: jasonsa - confirm works HCTraceSetTraceToDebugger(true); // CODE SNIPPET END diff --git a/Tests/ApiExplorer/APIs/apis_xal.cpp b/Tests/ApiExplorer/APIs/apis_xal.cpp index e2464177..395bfb54 100644 --- a/Tests/ApiExplorer/APIs/apis_xal.cpp +++ b/Tests/ApiExplorer/APIs/apis_xal.cpp @@ -56,7 +56,9 @@ void SetupXalNsalMock() if (hr == E_HC_NOT_INITIALISED) { // This happens on GDK where XAL is just a wrapper around XUser + LogToScreen("Calling HCInitialize()"); hr = HCInitialize(nullptr); + LogToScreen("HCInitialize done"); assert(SUCCEEDED(hr)); Data()->libHttpClientInit = true; hr = HCMockCallCreate(&(Data()->nsalMockCall)); diff --git a/Tests/ApiExplorer/APIs/apis_xblc.cpp b/Tests/ApiExplorer/APIs/apis_xblc.cpp index ed02f36a..a9e12f5b 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc.cpp @@ -32,6 +32,7 @@ int XblInitialize_Lua(lua_State *L) HRESULT hr = XblInitialize(&args); // CODE SNIPPET END XblDisableAssertsForXboxLiveThrottlingInDevSandboxes(XblConfigSetting::ThisCodeNeedsToBeChanged); + LogToFile("XblInitialize: %s", ConvertHR(hr).c_str()); return LuaReturnHR(L, hr); } @@ -117,8 +118,13 @@ int XblCleanupAsync_Lua(lua_State *L) hr = XAsyncGetStatus(asyncBlock.get(), true); } // CODE SNIPPET END - LogToFile("XblCleanup: hr=%s", ConvertHR(hr).data()); + + // Ignore not init'd error + if (hr == E_XBL_NOT_INITIALIZED) + { + hr = S_OK; + } return LuaReturnHR(L, S_OK); } diff --git a/Tests/ApiExplorer/APIs/apis_xblc_achievement_unlock_notification.cpp b/Tests/ApiExplorer/APIs/apis_xblc_achievement_unlock_notification.cpp index 372f52f3..dba9d10b 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_achievement_unlock_notification.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_achievement_unlock_notification.cpp @@ -102,12 +102,12 @@ void CALLBACK AchievementUnlockHandler(const XblAchievementUnlockEvent* args, vo { UNREFERENCED_PARAMETER(context); LogToScreen("Achievement Unlock Notification"); - LogToScreen("titleId: %s", args->titleId); + LogToScreen("titleId: %u", args->titleId); LogToScreen("achievementName: %s", args->achievementName); LogToScreen("achievementIcon: %s", args->achievementIcon); LogToScreen("gamerscore: %u", args->gamerscore); LogToScreen("rarityPercentage: %f", args->rarityPercentage); - LogToScreen("rarityCategory: %s", args->rarityCategory); + LogToScreen("rarityCategory: %u", static_cast(args->rarityCategory)); errorCode = status::OK; } diff --git a/Tests/ApiExplorer/APIs/apis_xblc_achievements_manager.cpp b/Tests/ApiExplorer/APIs/apis_xblc_achievements_manager.cpp index 3cba8ec5..9e8a75c7 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_achievements_manager.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_achievements_manager.cpp @@ -138,17 +138,27 @@ int SetupAchievementsManagerPerformanceTestMock_Lua(lua_State *L) int XblAchievementsManagerResultGetAchievements_Lua(lua_State *L) { auto resultHandle{ reinterpret_cast(GetUint64FromLua(L, 1, reinterpret_cast(achievementsState.achievementsResultHandle))) }; - // CODE SNIPPET START: XblAchievementsManagerResultGetAchievements_C - const XblAchievement* achievements = nullptr; - uint64_t achievementsCount = 0; - HRESULT hr = XblAchievementsManagerResultGetAchievements(resultHandle, &achievements, &achievementsCount); + if (resultHandle != nullptr) // might be null if original call fails + { + // CODE SNIPPET START: XblAchievementsManagerResultGetAchievements_C + const XblAchievement* achievements = nullptr; + uint64_t achievementsCount = 0; + HRESULT hr = XblAchievementsManagerResultGetAchievements(resultHandle, &achievements, &achievementsCount); - LogToScreen("Got %u Achievements:", achievementsCount); - // CODE SNIPPET END - lua_pushinteger(L, static_cast(achievementsCount)); + LogToScreen("Got %u Achievements:", achievementsCount); + // CODE SNIPPET END + lua_pushinteger(L, static_cast(achievementsCount)); + LogToScreen("XblAchievementsManagerResultGetAchievements: hr=%s", ConvertHR(hr).c_str()); + return LuaReturnHR(L, hr, 1); + } + else + { + HRESULT hr = S_OK; + lua_pushinteger(L, static_cast(0)); + LogToScreen("XblAchievementsManagerResultGetAchievements: hr=%s", ConvertHR(hr).c_str()); + return LuaReturnHR(L, hr, 1); + } - LogToScreen("XblAchievementsManagerResultGetAchievements: hr=%s", ConvertHR(hr).c_str()); - return LuaReturnHR(L, hr, 1); } int XblAchievementsManagerResultDuplicateHandle_Lua(lua_State *L) diff --git a/Tests/ApiExplorer/APIs/apis_xblc_multiplayer.cpp b/Tests/ApiExplorer/APIs/apis_xblc_multiplayer.cpp index bf815118..898bd21c 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_multiplayer.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_multiplayer.cpp @@ -170,7 +170,6 @@ int XblMultiplayerWriteSessionAsync_Lua(lua_State *L) else { LogToFile("XblMultiplayerWriteSessionResult: hr=%s", ConvertHR(hr).c_str()); // CODE SNIP SKIP - hr = S_OK; } CallLuaFunctionWithHr(hr, "OnXblMultiplayerWriteSessionAsync"); // CODE SNIP SKIP @@ -1055,17 +1054,21 @@ int XblMultiplayerSessionSetServerConnectionStringCandidates_Lua(lua_State *L) std::string candidate1 = GetStringFromLua(L, 1, "Candidate1"); std::string candidate2 = GetStringFromLua(L, 2, "Candidate1"); auto sessionHandle = GetSessionHandleFromArg(L, 3); - // CODE SNIPPET START: XblMultiplayerSessionSetServerConnectionStringCandidates - const char* serverConnectionStringCandidates[2] = {}; - serverConnectionStringCandidates[0] = candidate1.c_str(); - serverConnectionStringCandidates[1] = candidate2.c_str(); - size_t serverConnectionStringCandidatesCount = 2; + HRESULT hr = S_OK; + if (sessionHandle != nullptr) // might be null if previous call fails + { + // CODE SNIPPET START: XblMultiplayerSessionSetServerConnectionStringCandidates + const char* serverConnectionStringCandidates[2] = {}; + serverConnectionStringCandidates[0] = candidate1.c_str(); + serverConnectionStringCandidates[1] = candidate2.c_str(); + size_t serverConnectionStringCandidatesCount = 2; - HRESULT hr = XblMultiplayerSessionSetServerConnectionStringCandidates( - sessionHandle, - serverConnectionStringCandidates, - serverConnectionStringCandidatesCount); - // CODE SNIPPET END + hr = XblMultiplayerSessionSetServerConnectionStringCandidates( + sessionHandle, + serverConnectionStringCandidates, + serverConnectionStringCandidatesCount); + // CODE SNIPPET END + } LogToFile("XblMultiplayerSessionSetServerConnectionStringCandidates: hr=%s", ConvertHR(hr).c_str()); return LuaReturnHR(L, hr); @@ -1132,10 +1135,10 @@ int XblMultiplayerSessionCurrentUserSetSecureDeviceAddressBase64_Lua(lua_State * int XblFormatSecureDeviceAddress_Lua(lua_State *L) { +#if HC_PLATFORM != HC_PLATFORM_XDK && HC_PLATFORM != HC_PLATFORM_UWP std::string deviceIdStr = GetStringFromLua(L, 1, "ExampleDeviceAddress"); auto deviceId = deviceIdStr.c_str(); -#if HC_PLATFORM != HC_PLATFORM_XDK && HC_PLATFORM != HC_PLATFORM_UWP // CODE SNIPPET START: XblFormatSecureDeviceAddress XblFormattedSecureDeviceAddress address{ }; HRESULT hr = XblFormatSecureDeviceAddress(deviceId, &address); @@ -1307,11 +1310,15 @@ int XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson_Lua(lua_State std::string consts = GetStringFromLua(L, 1, "{}"); auto sessionHandle = GetSessionHandleFromArg(L, 2); - // CODE SNIPPET START: XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson - HRESULT hr = XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson( - sessionHandle, - consts.c_str()); - // CODE SNIPPET END + HRESULT hr = S_OK; + if (sessionHandle != nullptr) // might be null if previous call fails + { + // CODE SNIPPET START: XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson + hr = XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson( + sessionHandle, + consts.c_str()); + // CODE SNIPPET END + } LogToFile("XblMultiplayerSessionSetMatchmakingTargetSessionConstantsJson: hr=%s", ConvertHR(hr).c_str()); return LuaReturnHR(L, hr); diff --git a/Tests/ApiExplorer/APIs/apis_xblc_multiplayer_manager.cpp b/Tests/ApiExplorer/APIs/apis_xblc_multiplayer_manager.cpp index 518b093a..fdd8dfe4 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_multiplayer_manager.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_multiplayer_manager.cpp @@ -3,6 +3,15 @@ #include "pch.h" #include +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4061 ) +#pragma warning( disable : 4996 ) +#endif + +#include "rapidjson/document.h" + static std::thread s_doWorkThread{}; static std::atomic s_doWork{ false }; @@ -168,17 +177,15 @@ HRESULT MultiplayerManagerDoWork() auto h = events[i].Result; if (SUCCEEDED(h)) { - h = S_OK; - } + // Handle UserAdded + uint64_t xuid = 0; + hr = XblMultiplayerEventArgsXuid(events[i].EventArgsHandle, &xuid); + assert(SUCCEEDED(hr)); - // Handle UserAdded - uint64_t xuid = 0; - hr = XblMultiplayerEventArgsXuid(events[i].EventArgsHandle, &xuid); - assert(SUCCEEDED(hr)); - - CheckMemberFound(events[i].SessionType, xuid); - - LogToScreen("XblMultiplayerManagerDoWork event XblMultiplayerEventType::UserAdded. XUID: %llu", static_cast(xuid)); // CODE SNIP SKIP + CheckMemberFound(events[i].SessionType, xuid); + LogToScreen("XblMultiplayerManagerDoWork event XblMultiplayerEventType::UserAdded. XUID: %llu", static_cast(xuid)); // CODE SNIP SKIP + } + CallLuaFunctionWithHr(events[i].Result, "OnXblMultiplayerEventType_UserAdded"); // CODE SNIP SKIP break; } @@ -212,10 +219,13 @@ HRESULT MultiplayerManagerDoWork() hr = XblMultiplayerEventArgsXuid(events[i].EventArgsHandle, &xuid); assert(SUCCEEDED(hr)); - CheckMemberFound(events[i].SessionType, xuid); + if (SUCCEEDED(events[i].Result)) + { + CheckMemberFound(events[i].SessionType, xuid); - hr = events[i].Result == __HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND) ? S_OK : events[i].Result; - LogToScreen("XblMultiplayerManagerDoWork event XblMultiplayerEventType::JoinLobbyCompleted"); // CODE SNIP SKIP + hr = events[i].Result == __HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND) ? S_OK : events[i].Result; + LogToScreen("XblMultiplayerManagerDoWork event XblMultiplayerEventType::JoinLobbyCompleted"); // CODE SNIP SKIP + } CallLuaFunctionWithHr(hr, "OnXblMultiplayerEventType_JoinLobbyCompleted"); // CODE SNIP SKIP break; } @@ -433,6 +443,9 @@ HRESULT MultiplayerManagerDoWork() break; } + case XblMultiplayerEventType::TournamentRegistrationStateChanged: + case XblMultiplayerEventType::TournamentGameSessionReady: + case XblMultiplayerEventType::ArbitrationComplete: default: { LogToScreen("Received MPM event of type %u, hr=%s", events[i].EventType, ConvertHR(events[i].Result).data()); // CODE SNIP SKIP @@ -1323,3 +1336,6 @@ void SetupAPIs_XblMultiplayerManager() lua_register(Data()->L, "VerifyMPMLobbySessionProperites", VerifyMPMLobbySessionProperites_Lua); } +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif diff --git a/Tests/ApiExplorer/APIs/apis_xblc_stats2017.cpp b/Tests/ApiExplorer/APIs/apis_xblc_stats2017.cpp index 27f90fc2..34d7ae1c 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_stats2017.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_stats2017.cpp @@ -2,8 +2,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4061 ) +#pragma warning( disable : 4996 ) +#endif #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" +#include "rapidjson/document.h" +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif + +using namespace utility; struct StatsValueDocument { @@ -31,6 +43,7 @@ public: return *this; } + StatsValueDocument() noexcept = default; ~StatsValueDocument() noexcept = default; bool operator==(const StatsValueDocument& other) const noexcept @@ -107,7 +120,7 @@ private: static std::unique_ptr s_svd{ nullptr }; -StatsValueDocument GetStatsValueDocument(uint64_t xuid) +StatsValueDocument GetStatsValueDocument(uint64_t xuid, HRESULT* resultHr) { XblHttpCallHandle call{}; @@ -122,28 +135,44 @@ StatsValueDocument GetStatsValueDocument(uint64_t xuid) assert(SUCCEEDED(hr)); hr = XAsyncGetStatus(&async, true); - assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) + { + assert(SUCCEEDED(hr)); - const char* responseString{ nullptr }; - hr = XblHttpCallGetResponseString(call, &responseString); - assert(SUCCEEDED(hr)); + const char* responseString{ nullptr }; + hr = XblHttpCallGetResponseString(call, &responseString); + assert(SUCCEEDED(hr)); - rapidjson::Document svd{}; - svd.Parse(responseString); - assert(!svd.HasParseError()); + rapidjson::Document svd{}; + svd.Parse(responseString); + assert(!svd.HasParseError()); - return StatsValueDocument{ std::move(svd) }; + *resultHr = S_OK; + return StatsValueDocument{ std::move(svd) }; + } + else + { + *resultHr = E_FAIL; + return StatsValueDocument(); + } } int XblTitleManagedStatsWriteAsyncWithSVD_Lua(lua_State *L) { if (!s_svd) { - s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId)); + HRESULT hr = S_OK; + s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId, &hr)); + if (FAILED(hr)) + { + LogToFile("XblTitleManagedStatsWriteAsyncWithSVD: hr = %s", ConvertHR(hr).data()); + s_svd = nullptr; + return LuaReturnHR(L, hr); + } } - auto now = utility::datetime::utc_now(); - auto timeString = utility::conversions::to_utf8string(now.to_string(utility::datetime::date_format::ISO_8601)); + auto now = datetime::utc_now(); + auto timeString = conversions::to_utf8string(now.to_string(datetime::date_format::ISO_8601)); s_svd->SetStat("TimeString", timeString.data()); s_svd->SetStat("NumericStat", 100.0); @@ -235,10 +264,17 @@ int XblTitleManagedStatsUpdateStatsAsync_Lua(lua_State* L) { if (!s_svd) { - s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId)); + HRESULT hr = S_OK; + s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId, &hr)); + if (FAILED(hr)) + { + LogToFile("XblTitleManagedStatsWriteAsyncWithSVD: hr = %s", ConvertHR(hr).data()); + s_svd = nullptr; + return LuaReturnHR(L, hr); + } } - auto timeString = utility::conversions::to_utf8string(utility::datetime::utc_now().to_string(utility::datetime::date_format::ISO_8601)); + auto timeString = conversions::to_utf8string(datetime::utc_now().to_string(datetime::date_format::ISO_8601)); s_svd->SetStat("AddedStat",timeString.data()); s_svd->SetStat("NumericStat", 85.0); @@ -287,7 +323,14 @@ int XblTitleManagedStatsDeleteStatsAsync_Lua(lua_State* L) { if (!s_svd) { - s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId)); + HRESULT hr = S_OK; + s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId, &hr)); + if (FAILED(hr)) + { + LogToFile("XblTitleManagedStatsWriteAsyncWithSVD: hr = %s", ConvertHR(hr).data()); + s_svd = nullptr; + return LuaReturnHR(L, hr); + } } // CODE SNIPPET START: XblTitleManagedStatsDeleteStats @@ -330,7 +373,14 @@ int ValidateSVD_Lua(lua_State* L) // update. Just make sure we are in sync once at the end of the test. if (s_svd) { - auto updatedSVD{ GetStatsValueDocument(Data()->xboxUserId) }; + + HRESULT hr = S_OK; + auto updatedSVD{ GetStatsValueDocument(Data()->xboxUserId, &hr) }; + if (FAILED(hr)) + { + return 0; + } + LogToFile("Service SVD: %s", updatedSVD.Serialize().data()); LogToFile("Local SVD: %s", s_svd->Serialize().data()); assert(*s_svd == updatedSVD); @@ -345,7 +395,14 @@ int ClearSVD_Lua(lua_State* L) if (!s_svd) { - s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId)); + HRESULT hr = S_OK; + s_svd = std::make_unique(GetStatsValueDocument(Data()->xboxUserId, &hr)); + if (FAILED(hr)) + { + LogToFile("XblTitleManagedStatsWriteAsyncWithSVD: hr = %s", ConvertHR(hr).data()); + s_svd = nullptr; + return LuaReturnHR(L, hr); + } } s_svd->ClearStats(); return 0; diff --git a/Tests/ApiExplorer/APIs/apis_xblc_title_storage.cpp b/Tests/ApiExplorer/APIs/apis_xblc_title_storage.cpp index ad3bf350..7e977a2a 100644 --- a/Tests/ApiExplorer/APIs/apis_xblc_title_storage.cpp +++ b/Tests/ApiExplorer/APIs/apis_xblc_title_storage.cpp @@ -1,6 +1,74 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" +#include "rapidjson/document.h" + +#define CHECKHR(hr) if (FAILED(hr)) goto Cleanup; +// +/// Metadata about a blob. +/// +typedef struct JsonStorageBlobMetadata +{ + /// + /// Blob path is a unique string that conforms to a SubPath\file format (example: "foo\bar\blob.txt"). + /// + std::string blobPath; + + /// + /// [optional] Friendly display name to show in app UI. + /// + std::string displayName; + + /// + /// Gets the number of bytes of the blob data. + /// + size_t length; + + /// + /// Gets the position in the list of blob metadata + /// + size_t positionInList; + +} JsonStorageBlobMetadata; + + +struct JsonBlobMetadataResult : public std::enable_shared_from_this +{ + std::string m_scid; + uint64_t m_xuid; + std::string m_blobPath; + + std::vector m_items; + std::string m_continuationToken; +}; + +JsonBlobMetadataResult DeserializeResult(std::string blobPathRoot, std::string json) +{ + rapidjson::Document document; + document.Parse(json.c_str()); + + JsonBlobMetadataResult result; + + // Deserialize blobs + std::vector metadataList; + + size_t index = 0; + for (const auto& blobJson : document["blobs"].GetArray()) + { + JsonStorageBlobMetadata metadata; + metadata.blobPath = blobPathRoot + blobJson["fileName"].GetString(); + if (blobJson.HasMember("displayName")) + { + metadata.displayName = blobJson["displayName"].GetString(); + } + metadata.length = blobJson["size"].GetInt(); + metadata.positionInList = index; + index++; + result.m_items.push_back(metadata); + } + + return result; +} XblTitleStorageType ConvertStringToXblTitleStorageType(const char* str) { @@ -521,8 +589,129 @@ int XblTitleStorageUploadBinaryBlobAsync_Lua(lua_State *L) return LuaReturnHR(L, hr); } +int RestCallForEachBlob_Lua(lua_State *L) +{ + CreateQueueIfNeeded(); + auto response = Data()->responseString; + HRESULT hr = S_OK; + + auto result = DeserializeResult("https://titlestorage.xboxlive.com/universalplatform/users/xuid(2814654044759996)/scids/00000000-0000-0000-0000-000076029b4d/data/", response); + for (const auto& blobMetadata : result.m_items) + { + // Download the blob + XblHttpCallHandle output; + hr = XblHttpCallCreate(Data()->xboxLiveContext, "GET", blobMetadata.blobPath.c_str(), &output); + XblHttpCallRequestSetHeader(output, "Content-Type", "application/json; charset=utf-8", true); + XblHttpCallRequestSetHeader(output, "Accept-Language", "en-US,en", true); + XblHttpCallRequestSetHeader(output, "x-xbl-contract-version", "2", true); + Data()->downloadHttpCalls.push_back(output); + + auto asyncBlock = std::make_unique(); + asyncBlock->queue = Data()->queue; + asyncBlock->context = Data()->downloadHttpCalls[blobMetadata.positionInList]; + asyncBlock->callback = [](XAsyncBlock* asyncBlock) + { + std::unique_ptr asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock* + HRESULT hr = XAsyncGetStatus(asyncBlock, false); + + if (SUCCEEDED(hr)) + { + auto httpCall = static_cast(asyncBlock->context); + + const char* responseString; + hr = XblHttpCallGetResponseString(httpCall, &responseString); + + LogToScreen("Response String: length %d, hr=%s", strlen(responseString), ConvertHR(hr).c_str()); + CHECKHR(hr); + + uint32_t statusCode; + hr = XblHttpCallGetStatusCode(httpCall, &statusCode); + LogToScreen("Status Code: %d, hr=%s", statusCode, ConvertHR(hr).c_str()); + CHECKHR(hr); + } + + Cleanup: + Data()->completedDownloads++; + if (Data()->completedDownloads == Data()->downloadHttpCalls.size()) + { + CallLuaFunctionWithHr(hr, "OnRestCallForEachBlob"); + } + + LogToScreen("XblHttpCallPerformAsync Completion: hr=%s", ConvertHR(hr).c_str()); + }; + + LogToScreen("Downloading %s", blobMetadata.blobPath.c_str()); + hr = XblHttpCallPerformAsync(output, XblHttpCallResponseBodyType::String, asyncBlock.get()); + if (SUCCEEDED(hr)) + { + // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership. + // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock* + asyncBlock.release(); + } + + } + + return LuaReturnHR(L, hr); +} + +int RestCallForTMSMetadata_Lua(lua_State *L) +{ + CreateQueueIfNeeded(); + std::string methodName = GetStringFromLua(L, 1, "GET"); + char url[300]; + sprintf_s(url, "https://titlestorage.xboxlive.com/universalplatform/users/xuid(%" PRIu64 ")/scids/00000000-0000-0000-0000-000076029b4d/data?maxItems=100", Data()->xboxUserId); + + XblHttpCallHandle output; + HRESULT hr = XblHttpCallCreate(Data()->xboxLiveContext, methodName.c_str(), url, &output); + XblHttpCallRequestSetHeader(output, "Content-Type", "application/json; charset=utf-8", true); + XblHttpCallRequestSetHeader(output, "Accept-Language", "en-US,en", true); + XblHttpCallRequestSetHeader(output, "x-xbl-contract-version", "2", true); + Data()->xblHttpCall = output; + + auto asyncBlock = std::make_unique(); + asyncBlock->queue = Data()->queue; + asyncBlock->context = Data()->xblHttpCall; + asyncBlock->callback = [](XAsyncBlock* asyncBlock) + { + std::unique_ptr asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock* + HRESULT hr = XAsyncGetStatus(asyncBlock, false); + LogToScreen("XblHttpCallPerformAsync result: hr=%s", ConvertHR(hr).c_str()); + + if (SUCCEEDED(hr)) + { + const char* responseString; + hr = XblHttpCallGetResponseString(Data()->xblHttpCall, &responseString); + Data()->responseString = responseString; + + LogToScreen("XblHttpCallResponseGetResponseString: length %d, hr=%s", strlen(responseString), ConvertHR(hr).c_str()); + CHECKHR(hr); + + uint32_t statusCode; + hr = XblHttpCallGetStatusCode(Data()->xblHttpCall, &statusCode); + LogToScreen("XblHttpCallResponseGetStatusCode: %d, hr=%s", statusCode, ConvertHR(hr).c_str()); + CHECKHR(hr); + } + + Cleanup: + LogToScreen("XblHttpCallPerformAsync Completion: hr=%s", ConvertHR(hr).c_str()); + CallLuaFunctionWithHr(hr, "OnXblTitleStorageRestTMSMetadata"); + }; + + hr = XblHttpCallPerformAsync(Data()->xblHttpCall, XblHttpCallResponseBodyType::String, asyncBlock.get()); + if (SUCCEEDED(hr)) + { + // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership. + // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock* + asyncBlock.release(); + } + + return LuaReturnHR(L, hr); +} + void SetupAPIs_XblTitleStorage() { + lua_register(Data()->L, "RestCallForTMSMetadata", RestCallForTMSMetadata_Lua); + lua_register(Data()->L, "RestCallForEachBlob", RestCallForEachBlob_Lua); lua_register(Data()->L, "XblTitleStorageBlobMetadataResultGetItems", XblTitleStorageBlobMetadataResultGetItems_Lua); lua_register(Data()->L, "XblTitleStorageBlobMetadataResultHasNext", XblTitleStorageBlobMetadataResultHasNext_Lua); lua_register(Data()->L, "XblTitleStorageBlobMetadataResultGetNextAsync", XblTitleStorageBlobMetadataResultGetNextAsync_Lua); diff --git a/Tests/ApiExplorer/Include/api_explorer.h b/Tests/ApiExplorer/Include/api_explorer.h index 6ff6c1af..e4500358 100644 --- a/Tests/ApiExplorer/Include/api_explorer.h +++ b/Tests/ApiExplorer/Include/api_explorer.h @@ -73,6 +73,7 @@ struct ApiExplorerData std::string m_onTaskQueueTerminateWithAsyncWait; bool m_repeatJsonCmds{ false }; bool m_wasTestSkipped{ false }; + bool m_trackUnhookedMemory{ false }; std::mutex m_catMessageLock; std::string m_catMessage; @@ -142,6 +143,12 @@ struct ApiExplorerData xbox::services::title_storage::title_storage_blob_metadata blobMetadataCpp{}; #endif + // Title Storage Rest API Calls Data + std::string responseString; + std::vector downloadHttpCalls; + size_t completedDownloads = 0; + size_t filesToDownload = 0; + // MP std::string inviteHandle; diff --git a/Tests/ApiExplorer/Include/multidevice.h b/Tests/ApiExplorer/Include/multidevice.h index b5685e90..f3da145b 100644 --- a/Tests/ApiExplorer/Include/multidevice.h +++ b/Tests/ApiExplorer/Include/multidevice.h @@ -1,7 +1,14 @@ #pragma once +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4266 ) +#endif #include "cpprest/http_msg.h" -#include "rapidjson/document.h" +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif struct ServerState { @@ -82,7 +89,7 @@ public: std::string GetSessionStateString() { return m_sessionState; } std::string GetStateValueFromKey(std::string key); bool IsDoPoll() { return m_doPoll; } - void ParseState(const rapidjson::Document& jsonDoc); + void ParseState(const std::string& responseString); HRESULT MakeCall( _In_ const std::string& method, diff --git a/Tests/ApiExplorer/Shared/commands.cpp b/Tests/ApiExplorer/Shared/commands.cpp index 9e894e95..18726143 100644 --- a/Tests/ApiExplorer/Shared/commands.cpp +++ b/Tests/ApiExplorer/Shared/commands.cpp @@ -3,6 +3,11 @@ #include "pch.h" #include "utils.h" #include "cpprest/json.h" +#include "mem_hook.h" + +#include +#include + #if HC_PLATFORM == HC_PLATFORM_IOS #define E_NOT_VALID_STATE E_FAIL @@ -205,6 +210,20 @@ void OnCmdHost(const std::vector& cmdLineTokens) } } +void OnCmdMemTrack(const std::vector& cmdLineTokens) +{ + if (cmdLineTokens.size() < 2) + { + LogToScreen("Try: memtrack bool. eg memtrack true"); + return; + } + + std::string enabledStr = cmdLineTokens[1]; + bool enabled = (enabledStr == "true"); + Data()->m_trackUnhookedMemory = enabled; + LogToScreen("TrackUnhookedMemory: %d", enabled); +} + void OnCmdJoin(const std::vector& cmdLineTokens) { if (cmdLineTokens.size() < 2) @@ -245,7 +264,7 @@ void OnCmdJoin(const std::vector& cmdLineTokens) } } -bool LoadFile(std::string fileNameInput) +bool LoadFile(const std::string& fileNameInput) { std::string strFilePath = pal::FindFile(fileNameInput); if (strFilePath.empty()) @@ -304,6 +323,46 @@ void WaitForXalCleanup() } } +void APIRunner_CleanupLeakCheck() +{ + auto memHook = GetApiRunnerMemHook(); + memHook->LogStats("CleanupLeakCheck"); + if (Data()->xboxLiveContext) + { + XblContextCloseHandle(Data()->xboxLiveContext); + Data()->xboxLiveContext = nullptr; + } + memHook->LogStats("CleanupLeakCheck post-XblContextCloseHandle"); + if (Data()->xalUser) + { + XalUserCloseHandle(Data()->xalUser); + Data()->xalUser = nullptr; + } + memHook->LogStats("CleanupLeakCheck post-XalUserCloseHandle"); + + XAsyncBlock block{}; + HRESULT hr = XblCleanupAsync(&block); + if (SUCCEEDED(hr)) + { + hr = XAsyncGetStatus(&block, true); + } + memHook->LogStats("CleanupLeakCheck post-XblCleanupAsync"); + + hr = XalCleanupAsync(&block); + if (SUCCEEDED(hr)) + { + hr = XAsyncGetStatus(&block, true); + } + + if (Data()->queue != nullptr) + { + XTaskQueueCloseHandle(Data()->queue); + Data()->queue = nullptr; + } + memHook->LogStats("CleanupLeakCheck post-XalCleanupAsync"); + memHook->LogLeaks(); +} + HRESULT RunTestWithoutCleanup(const std::string& scriptName) { assert(!scriptName.empty()); @@ -336,7 +395,6 @@ HRESULT RunTestInternal(std::string testName, bool overrideSkip) CallLuaString("api = require 'u-test'; api.skipOverride = false;"); } - RunTestWithoutCleanup(testName); } @@ -409,6 +467,27 @@ void EnableTestSet(TestSet set) } } +void OnCmdFaultInjection(const std::vector& cmdLineTokens) +{ + assert(cmdLineTokens.size() >= 2); + if (pal::stricmp(cmdLineTokens[1].c_str(), "user") == 0) + { + XblEnableFaultInjection(INJECTION_FEATURE_USER); + } + if (pal::stricmp(cmdLineTokens[1].c_str(), "http") == 0) + { + XblEnableFaultInjection(INJECTION_FEATURE_HTTP); + } + if (pal::stricmp(cmdLineTokens[1].c_str(), "options") == 0) + { + assert(cmdLineTokens.size() == 5); + int64_t failFreq = static_cast(atoi(cmdLineTokens[2].c_str())); + uint64_t freqChangeSpeed = static_cast(atoi(cmdLineTokens[3].c_str())); + int64_t freqChangeAmount = static_cast(atoi(cmdLineTokens[4].c_str())); + XblSetFaultInjectOptions(failFreq, freqChangeSpeed, freqChangeAmount); + } +} + void OnCmdRunScript(const std::vector& cmdLineTokens) { assert(cmdLineTokens.size() == 2); @@ -451,6 +530,11 @@ HRESULT RunTestsHelper(TestSet set) SetupLua(); LogToScreen("Signing in silent if possible"); + if (Data()->m_trackUnhookedMemory) + { + auto memHook = GetApiRunnerMemHook(); + memHook->StartMemTracking(); + } HRESULT hr = RunSetupScript(); if (FAILED(hr)) @@ -489,7 +573,7 @@ HRESULT RunTestsHelper(TestSet set) continue; } - if (Data()->m_minFileNumber > 0 && Data()->m_maxFileNumber > 0) + if (Data()->m_minFileNumber > 0 || Data()->m_maxFileNumber > 0) { // Skip files outside range if (iFileNumber < Data()->m_minFileNumber || @@ -535,6 +619,12 @@ HRESULT RunTestsHelper(TestSet set) Data()->m_wasTestSkipped = false; } + if (Data()->m_trackUnhookedMemory) + { + auto memHook = GetApiRunnerMemHook(); + memHook->LogUnhookedStats(); + } + CallLuaString("test.summary()"); CleanupLua(); @@ -803,6 +893,12 @@ HRESULT ApiRunnerRunTestWithSetup(std::string testName, bool repeat) return E_UNEXPECTED; } + if (Data()->m_trackUnhookedMemory) + { + auto memHook = GetApiRunnerMemHook(); + memHook->StartMemTracking(); + } + Data()->m_runningTests = true; SetupLua(); HRESULT hr = RunSetupScript(); @@ -829,6 +925,13 @@ HRESULT ApiRunnerRunTestWithSetup(std::string testName, bool repeat) hr = RunTestInternal(testName, true); } } + + if (Data()->m_trackUnhookedMemory) + { + auto memHook = GetApiRunnerMemHook(); + memHook->LogUnhookedStats(); + } + CleanupLua(); Data()->m_runningTests = false; @@ -865,12 +968,27 @@ bool IsFailHr(HRESULT hr) return true; } +void OutputDebugStackTrace(std::vector stackTrace) +{ + LogToScreen("----------- BEGIN STACK TRACE -----------"); + for (std::string stack_string : stackTrace) + { + LogToScreen(stack_string.c_str()); + } + LogToScreen("----------- END STACK TRACE -----------"); +} + void LuaStopTestIfFailed(HRESULT hr) { Data()->m_lastError = hr; if (FAILED(hr) && Data()->m_checkHR) { char text[1024]; + + auto memHook = GetApiRunnerMemHook(); + std::vector stackTrace = memHook->GetStackLogLine(); + OutputDebugStackTrace(stackTrace); + sprintf_s(text, "local hr = 0x%0.8x; test.equal_no_log(hr, 0); test.stopTest();", hr); std::lock_guard lock(Data()->m_luaLock); if (Data()->L != nullptr) @@ -1043,12 +1161,13 @@ void SetupCommands() Data()->m_commands.push_back({ "rts", OnCmdRunTests, true }); Data()->m_commands.push_back({ "run", OnCmdRunTests, true }); Data()->m_commands.push_back({ "runbvts", OnCmdRunBvts, false }); - Data()->m_commands.push_back({ "runscript", OnCmdRunScript, true }); - Data()->m_commands.push_back({ "rs", OnCmdRunScript, true }); + Data()->m_commands.push_back({ "runbarescript", OnCmdRunScript, true }); + Data()->m_commands.push_back({ "faultinjection", OnCmdFaultInjection, true }); Data()->m_commands.push_back({ "host", OnCmdHost, true }); Data()->m_commands.push_back({ "join", OnCmdJoin, true }); Data()->m_commands.push_back({ "runmultidevicetests", OnCmdMultiDeviceTests, true }); + Data()->m_commands.push_back({ "memtrack", OnCmdMemTrack, true }); } bool ApiRunnerIsRunningTests() diff --git a/Tests/ApiExplorer/Shared/mem_hook.cpp b/Tests/ApiExplorer/Shared/mem_hook.cpp new file mode 100644 index 00000000..35b892f5 --- /dev/null +++ b/Tests/ApiExplorer/Shared/mem_hook.cpp @@ -0,0 +1,546 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +#include "pch.h" +#include "mem_hook.h" + +#define TRACK_UNHOOKED_ALLOCS 1 + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK +#include +#include +#include +#include + +#define TRACE_MAX_STACK_FRAMES 1024 +#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024 +#endif + +ApiRunerMemHook* g_mem = new ApiRunerMemHook(); +bool g_rawMemHookInitTracking{ false }; + +ApiRunerMemHook* GetApiRunnerMemHook() +{ + return g_mem; +} + +_Ret_maybenull_ _Post_writable_byte_size_(size) void* STDAPIVCALLTYPE ApiRunnerMemManagerMemAlloc(_In_ size_t size, _In_ HCMemoryType) +{ + auto mem = GetApiRunnerMemHook(); + return mem->AllocMem(size); +} + +void STDAPIVCALLTYPE ApiRunnerMemManagerMemFree(_In_ _Post_invalid_ void* pointer, _In_ HCMemoryType) +{ + auto mem = GetApiRunnerMemHook(); + mem->DeleteMem(pointer); +} + +_Ret_maybenull_ _Post_writable_byte_size_(size) void* ApiRunnerMemManagerXalMemAlloc(size_t size, uint32_t) +{ + auto mem = GetApiRunnerMemHook(); + return mem->AllocMem(size); +} + +void ApiRunnerMemManagerXalMemFree(_In_ _Post_invalid_ void* pointer, uint32_t) +{ + auto mem = GetApiRunnerMemHook(); + mem->DeleteMem(pointer); +} + +bool ApiRunerMemHook::IsMemTrackingStarted() +{ + return m_startMemTracking && m_refCountInsideAlloc == 0; +} + +ApiRunerMemHook::ApiRunerMemHook() +{ + m_refCountInsideAlloc = 0; + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + m_process = GetCurrentProcess(); + SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_DEBUG | SYMOPT_DEFERRED_LOADS | SYMOPT_CASE_INSENSITIVE); + SymInitialize(m_process, NULL, TRUE); +#endif +} + +HRESULT ApiRunerMemHook::StartMemTracking() +{ + if (m_startMemTracking) + return S_OK; + + // libHttpClient hooks does not need to be called if XBL or XAL is hooked but for extra insurance during tests + HRESULT hr = HCMemSetFunctions(&ApiRunnerMemManagerXalMemAlloc, &ApiRunnerMemManagerXalMemFree); + assert(SUCCEEDED(hr)); + if (FAILED(hr)) + return hr; + + hr = XblMemSetFunctions(&ApiRunnerMemManagerMemAlloc, &ApiRunnerMemManagerMemFree); + assert(SUCCEEDED(hr)); + if (FAILED(hr)) + return hr; + + ResetStats(); + + m_startMemTracking = true; + g_rawMemHookInitTracking = true; + + return S_OK; +} + + +HRESULT ApiRunerMemHook::StopMemTracking() +{ + if (!m_startMemTracking) + return S_OK; + + HRESULT hr = HCMemSetFunctions(nullptr, nullptr); + assert(SUCCEEDED(hr)); + if (FAILED(hr)) + return hr; + + hr = XblMemSetFunctions(nullptr, nullptr); + assert(SUCCEEDED(hr)); + if (FAILED(hr)) + return hr; + + m_startMemTracking = false; + g_rawMemHookInitTracking = false; + + return S_OK; +} + + +std::vector ApiRunerMemHook::GetStackLogLine() +{ +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + StackInfo stackInfo{ 0 }; + GetStackTrace(stackInfo); + + std::vector logs; + logs.reserve(static_cast(stackInfo.stackSize)); + for (int i = 0; i < stackInfo.stackSize; i++) + { + char sz[1024]; + if (stackInfo.szStack[i][0] != 0) + { + sprintf_s(sz, "%.32s in %s: line: %lu", stackInfo.szStack[i], stackInfo.szFileNames[i], stackInfo.lineNumber[i]); + } + + logs.push_back(sz); + } + return logs; +#else + return std::vector(); +#endif +} + +void ApiRunerMemHook::AssertOnAllocOfId(uint64_t id) +{ + m_assertId = id; +} + +void* ApiRunerMemHook::AllocMem(_In_ size_t size) +{ +#if TRACK_UNHOOKED_ALLOCS == 1 + m_refCountInsideAlloc++; + std::lock_guard guard(m_lock); +#endif + + void* ptr = malloc(size); + +#if TRACK_UNHOOKED_ALLOCS == 1 + m_allocSizeMap[ptr] = size; + m_allocated += size; + m_allocId++; + m_allocIdMap[ptr] = m_allocId; + + if (m_allocId == m_assertId) + { + LogToFile("Breakpoint here"); + } + + m_mapStackLog[ptr] = GetStackLogLine(); + m_refCountInsideAlloc--; +#endif + + return ptr; +} + + +bool ApiRunerMemHook::IsMemHooked(void* p) +{ +#if TRACK_UNHOOKED_ALLOCS == 1 + std::lock_guard guard(m_lock); + auto it = m_allocSizeMap.find(p); + return (it != m_allocSizeMap.end()); +#else + return false; +#endif +} + +void ApiRunerMemHook::DeleteMem(_In_ _Post_invalid_ void* pointer) +{ +#if TRACK_UNHOOKED_ALLOCS == 1 + std::lock_guard guard(m_lock); + uint64_t size = 0; + auto it = m_allocSizeMap.find(pointer); + if (it != m_allocSizeMap.end()) + { + size = it->second; + m_allocSizeMap.erase(it); + } + else + { + // assert(false); + // Add the following ifdef above line 53 in internal_mem.h + // if this assertion is reached. This will help track down what process + // is being freed incorrectly. +#if 0 + static int s_id = 0; + std::wstringstream msg; + msg << L"s_id:" << s_id << L" p: 0x" << std::hex << p << "\n"; + OutputDebugString(msg.str().c_str()); + s_id++; +#endif + } + m_allocDeleted += size; +#endif + + free(pointer); +} + +void ApiRunerMemHook::ResetStats() +{ + std::lock_guard guard(m_lock); + m_allocated = 0; + m_allocDeleted = 0; + m_allocId = 0; + m_allocSizeMap.clear(); + m_mapStackLog.clear(); +} + +void ApiRunerMemHook::LogLeaks() +{ + std::lock_guard guard(m_lock); + LogToScreen("Leaks: -- START --"); + for (auto& it : m_allocSizeMap) + { + void* ptr = it.first; + uint64_t size = it.second; + auto& stackLog = m_mapStackLog[ptr]; + auto& id = m_allocIdMap[ptr]; + LogToScreen("[%d] %0.8x: %d from %s", id, ptr, size, stackLog[4].c_str()); + } + LogToScreen("Leaks: -- END --"); + + LogToFile("== Leak CSV Start =="); + for (auto& it : m_allocSizeMap) + { + void* ptr = it.first; + uint64_t size = it.second; + auto& stackLog = m_mapStackLog[ptr]; + auto& id = m_allocIdMap[ptr]; + int stackLineId{ 0 }; + for (auto& stackLine : stackLog) + { + stackLineId++; + LogToFile("%d,%0.8x,%d,%d,%s", id, ptr, size, stackLineId, stackLine.c_str()); + } + } + LogToFile("== Leak CSV End =="); + +} + +void ApiRunerMemHook::LogStats(const std::string& name) +{ + std::lock_guard guard(m_lock); + LogToScreen("%s mem: %u outstanding alloc, (%u total / %u deleted)", name.c_str(), m_allocated - m_allocDeleted, m_allocated, m_allocDeleted); +} + +// IsStackInsideCallback() needs non-allocating case insenstive string compare so using manual impl +char* stristr(const char* str1, const char* str2) +{ + const char* p1 = str1; + const char* p2 = str2; + const char* r = *p2 == 0 ? str1 : 0; + + while (*p1 != 0 && *p2 != 0) + { + if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2)) + { + if (r == 0) + { + r = p1; + } + + p2++; + } + else + { + p2 = str2; + if (r != 0) + { + p1 = r + 1; + } + + if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2)) + { + r = p1; + p2++; + } + else + { + r = 0; + } + } + + p1++; + } + + return *p2 == 0 ? (char*)r : 0; +} + +bool ApiRunerMemHook::IsStackInsideCallback(const char* stackSymbolName, const char* filePath) +{ + const char* found; + + found = stristr(stackSymbolName, "ExampleWebsocketMessageReceived"); + if (found != nullptr) + return true; + found = stristr(stackSymbolName, "ExampleWebsocketClosed"); + if (found != nullptr) + return true; + found = stristr(stackSymbolName, "WaitForTestResult"); + if (found != nullptr) + return true; + found = stristr(filePath, "\\Include\\xsapi-cpp\\"); + if (found != nullptr) + return true; + found = stristr(stackSymbolName, " list; + for (int i = 0; i < m_rawAllocMemorySpots; i++) + { + std::stringstream msg; + msg << m_allocTrace[i] << "(" << m_allocTraceLine[i] << ")"; + list.push_back(msg.str()); + } + + std::sort(list.begin(), list.end()); + list.erase(std::unique(list.begin(), list.end()), list.end()); + + for(std::string s : list) + { + LogToScreen(s.c_str()); + } + g_rawMemHookInitTracking = true; +} + +bool ApiRunerMemHook::IsStackInXSAPI(StackInfo& stackInfo) +{ +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + GetStackTrace(stackInfo); + + bool foundInXsapi = false; + for (int i = 0; i < stackInfo.stackSize; i++) + { + stackInfo.isInXsapi[i] = IsFilePathInXSAPI(stackInfo.szFileNames[i]); + if (stackInfo.isInXsapi[i]) + { + foundInXsapi = true; + } + } + + if (foundInXsapi) + { + bool foundCallback = IsStackFramesInsideCallback(&stackInfo); + if (foundCallback) + { + return false; + } + + bool foundTestCodeFirst = IsStackFramesInsideTestCode(&stackInfo); + if (foundTestCodeFirst) + { + return false; + } + + return true; + } +#else + UNREFERENCED_PARAMETER(stackInfo); +#endif + + return false; +} + +void ApiRunerMemHook::GetStackTrace(StackInfo &stackInfo) +{ +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + void* stack[TRACE_MAX_STACK_FRAMES] = { 0 }; + WORD numberOfFrames = CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL); + stackInfo.stackSize = numberOfFrames < 64 ? numberOfFrames : 64; + for (int i = 0; i < stackInfo.stackSize; i++) + { + stackInfo.szFileNames[i][0] = 0; + stackInfo.szStack[i][0] = 0; + stackInfo.lineNumber[i] = 0; + DWORD64 address = (DWORD64)(stack[i]); + + char buffer[sizeof(SYMBOL_INFO) + TRACE_MAX_FUNCTION_NAME_LENGTH * sizeof(CHAR)] = { 0 }; + PSYMBOL_INFO symbolInfo = (PSYMBOL_INFO)buffer; + symbolInfo->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH - 1; + symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO); + SymFromAddr(m_process, address, NULL, symbolInfo); + + DWORD displacement; + char line64Buffer[sizeof(IMAGEHLP_LINE64)] = { 0 }; + IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64*)line64Buffer; + line->SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + if (SymGetLineFromAddr64(m_process, address, &displacement, line)) + { +#if HC_PLATFORM_IS_MICROSOFT + strcpy_s(stackInfo.szFileNames[i], line->FileName); + strcpy_s(stackInfo.szStack[i], symbolInfo->Name); +#else + strcpy(stackInfo.szFileNames[i], line->FileName); + strcpy(stackInfo.szStack[i], symbolInfo->Name); +#endif + stackInfo.lineNumber[i] = line->LineNumber; + } + } +#else + memset(&stackInfo, 0, sizeof(StackInfo)); +#endif +} + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK +bool ApiRunerMemHook::IsStackFramesInsideTestCode(StackInfo* pStackInfo) +{ + for (int i = 0; i < pStackInfo->stackSize; i++) + { + if (pStackInfo->isInXsapi[i]) + return false; + + const char* found = stristr(pStackInfo->szFileNames[i], "\\apiexplorer\\"); + if (found != nullptr) + return true; + } + return false; +} + +bool ApiRunerMemHook::IsStackFramesInsideCallback(StackInfo* pStackInfo) +{ + for (int i = 0; i < pStackInfo->stackSize; i++) + { + if (IsStackInsideCallback(pStackInfo->szStack[i], pStackInfo->szFileNames[i])) + { + return true; + } + } + return false; +} +#endif + +#if TRACK_UNHOOKED_ALLOCS == 1 +using namespace std; +void* operator new(size_t size) +{ + if (g_rawMemHookInitTracking) + { + auto mem = GetApiRunnerMemHook(); + if (mem->IsMemTrackingStarted()) + { + StackInfo stackInfo{ 0 }; + bool isInXSAPI = mem->IsStackInXSAPI(stackInfo); + if (isInXSAPI) + { + for (int i = 0; i < stackInfo.stackSize; i++) + { + if (stackInfo.isInXsapi[i]) + { +#if HC_PLATFORM_IS_MICROSOFT + strcpy_s(mem->m_allocTrace[mem->m_rawAllocMemorySpots], stackInfo.szFileNames[i]); +#else + strcpy(mem->m_allocTrace[mem->m_rawAllocMemorySpots], stackInfo.szFileNames[i]); +#endif + mem->m_allocTraceLine[mem->m_rawAllocMemorySpots] = stackInfo.lineNumber[i]; + break; + } + } + + mem->m_rawAllocMemory += size; + mem->m_rawAllocMemorySpots++; + if (mem->m_rawAllocMemorySpots >= APIRUNNER_MAX_UNHOOKED_MEM_TRACKED) + { + mem->m_rawAllocMemorySpots = APIRUNNER_MAX_UNHOOKED_MEM_TRACKED - 1; + } + } + } + } + + void* p = malloc(size); + return p; +} + +void operator delete(void * p) +{ + if (g_rawMemHookInitTracking) + { + auto mem = GetApiRunnerMemHook(); + if (mem->IsMemHooked(p)) + { + // This shouldn't be mem hooked + assert(false); + } + } + + free(p); +} +#endif + diff --git a/Tests/ApiExplorer/Shared/mem_hook.h b/Tests/ApiExplorer/Shared/mem_hook.h new file mode 100644 index 00000000..b0109067 --- /dev/null +++ b/Tests/ApiExplorer/Shared/mem_hook.h @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +#pragma once +#include "pch.h" + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK +#include +#endif + +struct StackInfo +{ + int stackSize; + bool isInXsapi[64]; + DWORD lineNumber[64]; + char szFileNames[64][1024]; + char szStack[64][1024]; +}; + +#define APIRUNNER_MAX_UNHOOKED_MEM_TRACKED 1024 +class ApiRunerMemHook +{ +public: + ApiRunerMemHook(); + + HRESULT StartMemTracking(); + HRESULT StopMemTracking(); + + bool IsMemTrackingStarted(); + void ResetStats(); + void LogStats(const std::string& name); + void LogLeaks(); + void AssertOnAllocOfId(uint64_t id); + + _Ret_maybenull_ _Post_writable_byte_size_(size) void* AllocMem(_In_ size_t size); + void DeleteMem(_In_ _Post_invalid_ void* pointer); + std::vector GetStackLogLine(); + + bool IsStackInXSAPI(StackInfo& stackInfo); + bool IsMemHooked(void* p); + void GetStackTrace(StackInfo &stackInfo); + +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + bool IsStackFramesInsideTestCode(StackInfo* pStackInfo); + bool IsStackFramesInsideCallback(StackInfo* pStackInfo); +#endif + + bool IsFilePathInXSAPI(const char* filePath); + bool IsStackInsideCallback(const char* stackSymbolName, const char* filePath); + void LogUnhookedStats(); + uint64_t m_rawAllocMemory{ 0 }; + uint64_t m_rawAllocMemorySpots{ 0 }; + char m_allocTrace[APIRUNNER_MAX_UNHOOKED_MEM_TRACKED][1024] { 0 }; + unsigned long m_allocTraceLine[APIRUNNER_MAX_UNHOOKED_MEM_TRACKED] { 0 }; + +private: +#if HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM == HC_PLATFORM_GDK + HANDLE m_process{ nullptr }; +#endif + bool m_startMemTracking{ false }; + uint64_t m_allocated{ 0 }; + uint64_t m_allocDeleted{ 0 }; + uint64_t m_unhookedAllocated{ 0 }; + uint64_t m_unhookedDeleted{ 0 }; + uint64_t m_allocId{ 0 }; + uint64_t m_assertId{ 0 }; + std::recursive_mutex m_lock; + std::map< void*, uint64_t > m_allocSizeMap; + std::map< void*, uint64_t > m_allocIdMap; + std::map< void*, std::vector > m_mapStackLog; + std::atomic m_refCountInsideAlloc; +}; + +ApiRunerMemHook* GetApiRunnerMemHook(); diff --git a/Tests/ApiExplorer/Shared/multidevice.cpp b/Tests/ApiExplorer/Shared/multidevice.cpp index b6f84f99..d5d56d5e 100644 --- a/Tests/ApiExplorer/Shared/multidevice.cpp +++ b/Tests/ApiExplorer/Shared/multidevice.cpp @@ -1,6 +1,16 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4061 ) +#pragma warning( disable : 4996 ) +#endif +#include "rapidjson/document.h" +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif #if __has_include("apirunnercloudfns.h") #include "apirunnercloudfns.h" @@ -20,6 +30,8 @@ #define SPRINTF_XPLAT sprintf #endif +using namespace utility; + static std::thread s_watchThread{}; ApiRunnerMultiDeviceManager::~ApiRunnerMultiDeviceManager() @@ -54,12 +66,12 @@ HRESULT ApiRunnerMultiDeviceManager::JoinOpenSession( _In_ std::function handler) { auto manager = Data()->m_multiDeviceManager; - manager->m_nextCallTime = utility::datetime::utc_now() - utility::datetime::from_seconds(1); + manager->m_nextCallTime = datetime::utc_now() - datetime::from_seconds(1); manager->m_callGetJoinable = true; LogToScreen("MultiDevice: Looking for test session to join..."); while (!manager->Joined()) { - int64_t delta = static_cast(manager->m_nextCallTime.to_interval()) - static_cast(utility::datetime::utc_now().to_interval()); + int64_t delta = static_cast(manager->m_nextCallTime.to_interval()) - static_cast(datetime::utc_now().to_interval()); if (delta < 0 && manager->m_callGetJoinable) { manager->m_callGetJoinable = false; @@ -82,14 +94,14 @@ HRESULT ApiRunnerMultiDeviceManager::JoinOpenSession( else { auto manager = Data()->m_multiDeviceManager; - manager->m_nextCallTime = utility::datetime::utc_now() + utility::datetime::from_seconds(1); + manager->m_nextCallTime = datetime::utc_now() + datetime::from_seconds(1); manager->m_callGetJoinable = true; } }); } else { - manager->m_nextCallTime = utility::datetime::utc_now() + utility::datetime::from_seconds(1); + manager->m_nextCallTime = datetime::utc_now() + datetime::from_seconds(1); manager->m_callGetJoinable = true; } }); @@ -167,17 +179,17 @@ HRESULT ApiRunnerMultiDeviceManager::Init( HRESULT ApiRunnerMultiDeviceManager::WaitTillPeerConnects() { auto manager = Data()->m_multiDeviceManager; - manager->m_nextCallTime = utility::datetime::utc_now() - utility::datetime::from_seconds(1); + manager->m_nextCallTime = datetime::utc_now() - datetime::from_seconds(1); manager->m_callGetJoinable = true; std::string curSessionId = manager->m_sessionId; std::string name = manager->m_sessionName; LogToScreen("MultiDevice: Waiting for peer to connect to test session..."); while (!manager->Joined()) { - int64_t delta = static_cast(manager->m_nextCallTime.to_interval()) - static_cast(utility::datetime::utc_now().to_interval()); + int64_t delta = static_cast(manager->m_nextCallTime.to_interval()) - static_cast(datetime::utc_now().to_interval()); if (delta < 0) { - manager->m_nextCallTime = utility::datetime::utc_now() + utility::datetime::from_seconds(1); + manager->m_nextCallTime = datetime::utc_now() + datetime::from_seconds(1); std::string state = manager->GetSessionStateString(); if (state.length() > 0) { @@ -427,8 +439,12 @@ HRESULT ApiRunnerMultiDeviceManager::StopSessionStateChangePolling() return S_OK; } -void ApiRunnerMultiDeviceManager::ParseState(const rapidjson::Document& jsonDoc) + +void ApiRunnerMultiDeviceManager::ParseState(const std::string& responseString) { + rapidjson::Document jsonDoc; + jsonDoc.Parse(responseString.c_str()); + ServerState oldState; { std::lock_guard lock(m_mutex); @@ -491,7 +507,7 @@ HRESULT ApiRunnerMultiDeviceManager::RefreshSessionState() } if(oldState != responseString) { - manager->ParseState(jsonDoc); + manager->ParseState(responseString); } } } diff --git a/Tests/ApiExplorer/Shared/pch_apicommon.cpp b/Tests/ApiExplorer/Shared/pch_apicommon.cpp index 0aa0b655..07921bf5 100644 --- a/Tests/ApiExplorer/Shared/pch_apicommon.cpp +++ b/Tests/ApiExplorer/Shared/pch_apicommon.cpp @@ -1,3 +1,6 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch_common.h" +#if HC_PLATFORM != HC_PLATFORM_IOS +#include +#endif \ No newline at end of file diff --git a/Tests/ApiExplorer/Shared/pch_common.cpp b/Tests/ApiExplorer/Shared/pch_common.cpp index 37fc1d00..1efc9a53 100644 --- a/Tests/ApiExplorer/Shared/pch_common.cpp +++ b/Tests/ApiExplorer/Shared/pch_common.cpp @@ -2,3 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" #include "pch_common.h" + +// APIRunner uses cpprestsdk and XSAPI lib doesn't on non-GDK platforms +#if HC_PLATFORM == HC_PLATFORM_GDK +#include "cpprestsdk_impl.h" +#endif diff --git a/Tests/ApiExplorer/Shared/pch_common.h b/Tests/ApiExplorer/Shared/pch_common.h index 2dd38814..b27d4545 100644 --- a/Tests/ApiExplorer/Shared/pch_common.h +++ b/Tests/ApiExplorer/Shared/pch_common.h @@ -40,11 +40,19 @@ #include "pal.h" #include "utils.h" +#include "mem_hook.h" #include "lua.h" #include "lualib.h" #include "lauxlib.h" +#if XSAPI_BUILT_FROM_SOURCE +#undef RAPIDJSON_NAMESPACE +#undef RAPIDJSON_NAMESPACE_BEGIN +#undef RAPIDJSON_NAMESPACE_END +#endif +#include "../External/rapidjson/include/rapidjson/document.h" + #include "../Include/multidevice.h" #include "../Include/api_explorer.h" #include "../Include/runner.h" diff --git a/Tests/ApiExplorer/Shared/utils.h b/Tests/ApiExplorer/Shared/utils.h index 804f97ed..e0ddf357 100644 --- a/Tests/ApiExplorer/Shared/utils.h +++ b/Tests/ApiExplorer/Shared/utils.h @@ -5,6 +5,11 @@ #include #endif +// internal test-only APIs +#define NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN namespace xbox { namespace services { +#define NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END }} +#include "../Source/Shared/fault_injection.h" + #define VERIFY_IS_TRUE(x, y) if (SUCCEEDED(hr)) { hr = VerifyIsTrue(x, y); } #define ENSURE_IS_TRUE(x, y) if (FAILED(VerifyIsTrue(x, y))) return LuaReturnHR(L, E_ABORT); diff --git a/Tests/ApiExplorer/Tests/_luasetup_/xal/common.lua b/Tests/ApiExplorer/Tests/_luasetup_/xal/common.lua index 3d9917ca..3cb2199c 100644 --- a/Tests/ApiExplorer/Tests/_luasetup_/xal/common.lua +++ b/Tests/ApiExplorer/Tests/_luasetup_/xal/common.lua @@ -20,11 +20,28 @@ end function common.OnXalTryAddFirstUserSilentlyAsync() local hr = GetLastError() if hr == 0 then - XblContextCreateHandle() - XalUserGetGamertag() - XalUserGetId() + print("SignInSilently Succeeded. Creating XblContext") + hr = XblContextCreateHandle() + if hr == 0 then + XalUserGetGamertag() + XalUserGetId() + else + if GetCheckHR() == true then + test.stopTest(); + else + SetCheckHR(1) + end + end + common.functionAddFirstAsync() + else + print("SignInSilently Failed") + if GetCheckHR() == true then + test.stopTest(); + else + SetCheckHR(1) + common.functionAddFirstAsync() + end end - common.functionAddFirstAsync() end return common diff --git a/Tests/ApiExplorer/Tests/_luasetup_/xal/setup.lua b/Tests/ApiExplorer/Tests/_luasetup_/xal/setup.lua index 3e42ab0e..cce87ffd 100644 --- a/Tests/ApiExplorer/Tests/_luasetup_/xal/setup.lua +++ b/Tests/ApiExplorer/Tests/_luasetup_/xal/setup.lua @@ -3,8 +3,8 @@ test = require 'u-test' common = require 'common' function SetupTest_Handler() - local hr = GetLastError() print("SetupTest_Handler") + local hr = GetLastError() SetCheckHR(1) if hr ~= 0 then print("Calling XalAddUserWithUiAsync") diff --git a/Tests/ApiExplorer/Tests/cmds.json b/Tests/ApiExplorer/Tests/cmds.json index bc74ca85..54b3342c 100644 --- a/Tests/ApiExplorer/Tests/cmds.json +++ b/Tests/ApiExplorer/Tests/cmds.json @@ -14,13 +14,20 @@ "rem rt multiplayerManager\\MPM_Invite.lua", "rem rt multiplayerManager\\MPM_InviteUI.lua", - // single-device examples + // fault injection + "rem faultinjection options 1 7 1", // faultinjection options failFreq freqChangeSpeed freqChangeAmount + "rem faultinjection user", // "faultinjection" enables specific fault injection on specific features + "rem faultinjection http", // "faultinjection" enables specific fault injection on specific features + + // mem hook tracking + "rem memtrack true", // result logged after runtests or rt command ends + + // single-device command examples + "rem runbarescript misc\\global_state.lua", // "runbarescript" will run the script without any XBL/XAL initializtion for special test needs "rem rt achievements\\achievements_progress_notification.lua", "rem rt achievements\\achievements_manager_performance_test.lua", "rem rt achievements\\achievements_manager_update_achievements.lua", "rem rt gdk-gameinvite\\game-invite.lua", // rt will run a single test - "rem rt rta\\2HourTimeout.lua", - "rem rs misc\\global_state.lua", // "rs" will run the script without any initializtion for special test needs "rem repeat social\\social_manager_2.lua", // "repeat" will repeat this single test without cleanup forever "rem loop", // "loop" will loop the entire cmds.json file including cleanup, forever "runtests" // "runtests" will run all the single-device tests diff --git a/Tests/ApiExplorer/Tests/titleStorage/title_storage-restCalls.lua b/Tests/ApiExplorer/Tests/titleStorage/title_storage-restCalls.lua new file mode 100644 index 00000000..82b10114 --- /dev/null +++ b/Tests/ApiExplorer/Tests/titleStorage/title_storage-restCalls.lua @@ -0,0 +1,22 @@ +test = require 'u-test' +common = require 'common' + +function TitleStorageRestAPI() + print("TitleStorage"); + RestCallForTMSMetadata(); +end + +function OnXblTitleStorageRestTMSMetadata() + print('Calling RestCallForEachBlob') + RestCallForEachBlob(); +end + +function OnRestCallForEachBlob() + print('OnRestCallForEachBlob') + test.stopTest(); +end + +test.skip = true +test.TitleStorageRestAPI = function() + common.init(TitleStorageRestAPI) +end \ No newline at end of file diff --git a/Tests/GDK/APIRunner.GDK/APIRunner.GDK.Src.vcxproj b/Tests/GDK/APIRunner.GDK/APIRunner.GDK.Src.vcxproj index d42778a2..73b74858 100644 --- a/Tests/GDK/APIRunner.GDK/APIRunner.GDK.Src.vcxproj +++ b/Tests/GDK/APIRunner.GDK/APIRunner.GDK.Src.vcxproj @@ -50,7 +50,7 @@ x64 - + Application @@ -261,7 +261,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) true Windows true @@ -287,7 +287,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) true Windows true @@ -315,7 +315,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) true Windows true @@ -341,7 +341,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) true Windows true @@ -369,7 +369,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) Windows true @@ -392,7 +392,7 @@ - uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(XboxExtensionsDependencies);%(AdditionalDependencies) Windows true @@ -421,7 +421,7 @@ Windows true true - uuid.lib;$(Console_Libs);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(AdditionalDependencies) Use @@ -445,7 +445,7 @@ Windows true true - uuid.lib;$(Console_Libs);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(AdditionalDependencies) Use @@ -467,7 +467,7 @@ Windows true - uuid.lib;$(Console_Libs);%(AdditionalDependencies) + dbghelp.lib;uuid.lib;$(Console_Libs);%(AdditionalDependencies) pch.h @@ -523,7 +523,6 @@ - %(Filename)%(Extension) @@ -562,7 +561,6 @@ true - diff --git a/Tests/GDK/APIRunner.GDK/APIRunner.GDK.cpp b/Tests/GDK/APIRunner.GDK/APIRunner.GDK.cpp index aa8dcb6c..eacce2ec 100644 --- a/Tests/GDK/APIRunner.GDK/APIRunner.GDK.cpp +++ b/Tests/GDK/APIRunner.GDK/APIRunner.GDK.cpp @@ -158,7 +158,7 @@ DWORD WINAPI ApiRunnerDoWork(LPVOID ) void Sample::StartRunTests() { - if (!m_bRunningTests) + if (!m_bRunningTests && m_log) { m_bRunningTests = true; m_log->Clear(); @@ -474,8 +474,6 @@ void Sample::OnDeviceRestored() } #pragma endregion - - void LogToScreen(_Printf_format_string_ char const* format, ...) { char message[8000] = {}; @@ -498,4 +496,3 @@ void LogToScreen(_Printf_format_string_ char const* format, ...) LogToFile(message); } - \ No newline at end of file diff --git a/Tests/GDK/APIRunner.GDK/DeviceResources.cpp b/Tests/GDK/APIRunner.GDK/DeviceResources.cpp index 0ac1d939..d55f619f 100644 --- a/Tests/GDK/APIRunner.GDK/DeviceResources.cpp +++ b/Tests/GDK/APIRunner.GDK/DeviceResources.cpp @@ -113,35 +113,35 @@ void DeviceResources::CreateDeviceResources() // Enable the debug layer (requires the Graphics Tools "optional feature"). // // NOTE: Enabling the debug layer after device creation will invalidate the active device. - { - ComPtr debugController; - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf())))) - { - debugController->EnableDebugLayer(); - } - else - { - OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n"); - } + //{ + // ComPtr debugController; + // if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf())))) + // { + // debugController->EnableDebugLayer(); + // } + // else + // { + // OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n"); + // } - ComPtr dxgiInfoQueue; - if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf())))) - { - dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG; + // ComPtr dxgiInfoQueue; + // if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf())))) + // { + // dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG; - dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true); - dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true); + // dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true); + // dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true); - DXGI_INFO_QUEUE_MESSAGE_ID hide[] = - { - 80 /* IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides. */, - }; - DXGI_INFO_QUEUE_FILTER filter = {}; - filter.DenyList.NumIDs = _countof(hide); - filter.DenyList.pIDList = hide; - dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter); - } - } + // DXGI_INFO_QUEUE_MESSAGE_ID hide[] = + // { + // 80 /* IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides. */, + // }; + // DXGI_INFO_QUEUE_FILTER filter = {}; + // filter.DenyList.NumIDs = _countof(hide); + // filter.DenyList.pIDList = hide; + // dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter); + // } + //} #endif ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf()))); diff --git a/Tests/GDK/APIRunner.GDK/Kits/LiveTK/LiveResources.cpp b/Tests/GDK/APIRunner.GDK/Kits/LiveTK/LiveResources.cpp index 541a5a0e..84f09cfd 100644 --- a/Tests/GDK/APIRunner.GDK/Kits/LiveTK/LiveResources.cpp +++ b/Tests/GDK/APIRunner.GDK/Kits/LiveTK/LiveResources.cpp @@ -74,11 +74,6 @@ LiveResources::LiveResources(XTaskQueueHandle queue, bool autoManageUser, bool i char scidBuffer[64] = {}; sprintf_s(scidBuffer, "00000000-0000-0000-0000-0000%08x", m_titleId); - - XblInitArgs xblInit = { m_asyncQueue, scidBuffer }; - hr = XblInitialize(&xblInit); - DX::ThrowIfFailed(hr); - m_scid = scidBuffer; #ifdef _GAMING_XBOX diff --git a/Tests/GDK/APIRunner.GDK/Main.cpp b/Tests/GDK/APIRunner.GDK/Main.cpp index ef406142..9a58a493 100644 --- a/Tests/GDK/APIRunner.GDK/Main.cpp +++ b/Tests/GDK/APIRunner.GDK/Main.cpp @@ -14,6 +14,17 @@ #include #include +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( push ) +#pragma warning( disable : 4365 ) +#pragma warning( disable : 4061 ) +#pragma warning( disable : 4996 ) +#endif +#include +#if HC_PLATFORM_IS_MICROSOFT +#pragma warning( pop ) +#endif + #ifdef ATG_ENABLE_TELEMETRY #include "ATGTelemetry.h" #endif diff --git a/Tests/GDK/APIRunner.GDK/pch.cpp b/Tests/GDK/APIRunner.GDK/pch.cpp index 41be6fcf..06cf1b9e 100644 --- a/Tests/GDK/APIRunner.GDK/pch.cpp +++ b/Tests/GDK/APIRunner.GDK/pch.cpp @@ -1,3 +1,7 @@ // Copyright (c) Microsoft Corporation // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include "pch.h" + +// APIRunner itself (but not XSAPI lib) uses cpprestsdk on GDK platforms +#include "cpprestsdk_impl.h" + diff --git a/Tests/UnitTests/Mocks/http_mock.cpp b/Tests/UnitTests/Mocks/http_mock.cpp index 738ae6df..0bf94945 100644 --- a/Tests/UnitTests/Mocks/http_mock.cpp +++ b/Tests/UnitTests/Mocks/http_mock.cpp @@ -121,33 +121,33 @@ void HttpMock::SetMockMatchedCallback(MockMatchedCallback mockMatched) noexcept UNREFERENCED_PARAMETER(method); auto thisPtr{ static_cast(context) }; - thisPtr->m_matchedCallback(thisPtr, url, std::string{ requestBodyBytes, requestBodyBytes + requestBodySize }); + thisPtr->m_matchedCallback(thisPtr, url, xsapi_internal_string{ requestBodyBytes, requestBodyBytes + requestBodySize }); }, this ); } -std::string HttpMock::GetUriPath(const std::string& uriString) noexcept +xsapi_internal_string HttpMock::GetUriPath(const xsapi_internal_string& uriString) noexcept { - xbox::services::uri uri{ Utils::StringTFromUtf8(uriString.data()) }; - return Utils::StringFromStringT(uri.path()); + xbox::services::uri uri{ uriString.data() }; + return uri.path(); } -std::string HttpMock::GetUriQuery(const std::string& uriString) noexcept +xsapi_internal_string HttpMock::GetUriQuery(const xsapi_internal_string& uriString) noexcept { - xbox::services::uri uri{ Utils::StringTFromUtf8(uriString.data()) }; - return Utils::StringFromStringT(uri.query()); + xbox::services::uri uri{ uriString.data() }; + return uri.query(); } -std::map HttpMock::GetQueryParams(const std::string& uriString) noexcept +std::map HttpMock::GetQueryParams(const xsapi_internal_string& uriString) noexcept { - web::uri uri{ Utils::StringTFromUtf8(uriString.data()) }; - auto params = web::uri::split_query(uri.query()); + xbox::services::uri uri{ uriString.data() }; + auto params = xbox::services::uri::split_query(uri.query()); - std::map out; + std::map out; for (auto& param : params) { - out[Utils::StringFromStringT(param.first)] = Utils::StringFromStringT(param.second); + out[param.first.c_str()] = param.second.c_str(); } return out; } diff --git a/Tests/UnitTests/Mocks/http_mock.h b/Tests/UnitTests/Mocks/http_mock.h index 35cc2ab4..dc4376d4 100644 --- a/Tests/UnitTests/Mocks/http_mock.h +++ b/Tests/UnitTests/Mocks/http_mock.h @@ -11,7 +11,7 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN -typedef Callback MockMatchedCallback; +typedef Callback MockMatchedCallback; // RAII wrapper around HCMockCallHandle class HttpMock @@ -41,9 +41,9 @@ public: void SetMockMatchedCallback(MockMatchedCallback callback) noexcept; // Helper methods for parsing URI - static std::string GetUriPath(const std::string& uri) noexcept; - static std::string GetUriQuery(const std::string& uri) noexcept; - static std::map GetQueryParams(const std::string& uri) noexcept; + static xsapi_internal_string GetUriPath(const xsapi_internal_string& uri) noexcept; + static xsapi_internal_string GetUriQuery(const xsapi_internal_string& uri) noexcept; + static std::map GetQueryParams(const xsapi_internal_string& uriString) noexcept; private: HCMockCallHandle m_handle{ nullptr }; diff --git a/Tests/UnitTests/Mocks/mock_rta_service.cpp b/Tests/UnitTests/Mocks/mock_rta_service.cpp index 101713f9..b68707d3 100644 --- a/Tests/UnitTests/Mocks/mock_rta_service.cpp +++ b/Tests/UnitTests/Mocks/mock_rta_service.cpp @@ -153,7 +153,7 @@ void MockRealTimeActivityService::CompleteSubscribeHandshake( } void MockRealTimeActivityService::RaiseEvent( - const std::string& uri, + const xsapi_internal_string& uri, const rapidjson::Value& payload ) noexcept { @@ -189,7 +189,7 @@ void MockRealTimeActivityService::RaiseEvent( } void MockRealTimeActivityService::RaiseEvent( - const std::string& uri, + const xsapi_internal_string& uri, const char* payload ) noexcept { diff --git a/Tests/UnitTests/Mocks/mock_rta_service.h b/Tests/UnitTests/Mocks/mock_rta_service.h index 810d8c33..f413d6e1 100644 --- a/Tests/UnitTests/Mocks/mock_rta_service.h +++ b/Tests/UnitTests/Mocks/mock_rta_service.h @@ -31,7 +31,7 @@ public: ServiceUnavailable = 1002 }; - using SubscribeHandler = std::function; + using SubscribeHandler = std::function; void SetSubscribeHandler( SubscribeHandler handler ) noexcept; @@ -49,12 +49,12 @@ public: ) noexcept; void RaiseEvent( - const std::string& uri, + const xsapi_internal_string& uri, const rapidjson::Value& payload ) noexcept; void RaiseEvent( - const std::string& uri, + const xsapi_internal_string& uri, const char* payload ) noexcept; @@ -72,7 +72,7 @@ private: struct Subscription { - std::string uri; + xsapi_internal_string uri; uint32_t clientSequenceNumber{ 0 }; bool active{ false }; }; diff --git a/Tests/UnitTests/Support/TAEF/UnitTestBase.cpp b/Tests/UnitTests/Support/TAEF/UnitTestBase.cpp index 89cb270a..465fdfbd 100644 --- a/Tests/UnitTests/Support/TAEF/UnitTestBase.cpp +++ b/Tests/UnitTests/Support/TAEF/UnitTestBase.cpp @@ -7,7 +7,6 @@ #include #if USING_TAEF #include "WexTestClass.h" -#include "telemetry.h" #include #else #include @@ -74,8 +73,6 @@ std::wstring FormatString(LPCWSTR strMsg, ...) /// The message to log void LogFormatString(LPCWSTR strMsg, ...) { - TraceLoggingWrite(g_hUnitTestTraceLoggingProvider, "UnitTest", TraceLoggingWideString(strMsg, "test_log")); - #ifdef USING_TAEF #if ENABLE_SCREEN_LOGGING WEX::Logging::Log::Comment(strMsg); diff --git a/Tests/UnitTests/Support/TAEF/UnitTestBase.h b/Tests/UnitTests/Support/TAEF/UnitTestBase.h index e91f7b78..a1ccd1e2 100644 --- a/Tests/UnitTests/Support/TAEF/UnitTestBase.h +++ b/Tests/UnitTests/Support/TAEF/UnitTestBase.h @@ -207,6 +207,6 @@ inline void VERIFY_IS_EQUAL_JSON_HELPER_FROM_STRINGS(xsapi_internal_string expec inline bool VerifyTime(time_t time, std::string timeString) { - auto datetime = xbox::services::datetime::from_string(xbox::services::utils::string_t_from_utf8(timeString.data()), xbox::services::datetime::date_format::ISO_8601); + auto datetime = xbox::services::datetime::from_string(timeString.data(), xbox::services::datetime::date_format::ISO_8601); return xbox::services::utils::time_t_from_datetime(datetime) == time; } \ No newline at end of file diff --git a/Tests/UnitTests/Support/unit_test_helpers.h b/Tests/UnitTests/Support/unit_test_helpers.h index 63275839..718aad0b 100644 --- a/Tests/UnitTests/Support/unit_test_helpers.h +++ b/Tests/UnitTests/Support/unit_test_helpers.h @@ -61,7 +61,7 @@ inline bool VerifyTime( const std::string& timeString ) { - auto datetime = xbox::services::datetime::from_string(xbox::services::Utils::StringTFromUtf8(timeString.data()), xbox::services::datetime::date_format::ISO_8601); + auto datetime = xbox::services::datetime::from_string(timeString.data(), xbox::services::datetime::date_format::ISO_8601); return xbox::services::utils::time_t_from_datetime(datetime) == time; } diff --git a/Tests/UnitTests/Tests/Services/AchievementsManagerTests.cpp b/Tests/UnitTests/Tests/Services/AchievementsManagerTests.cpp index e05769cc..1d6f51b6 100644 --- a/Tests/UnitTests/Tests/Services/AchievementsManagerTests.cpp +++ b/Tests/UnitTests/Tests/Services/AchievementsManagerTests.cpp @@ -1510,7 +1510,7 @@ private: { auto& mockRtaService{ MockRealTimeActivityService::Instance() }; mockRtaService.SetSubscribeHandler( - [&](uint32_t n, std::string) + [&](uint32_t n, xsapi_internal_string) { mockRtaService.CompleteSubscribeHandshake(n); } @@ -1537,10 +1537,10 @@ private: mock.SetResponseBody(defaultAchievementResponse); // mock the response of Get Achievements auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { - if (uri.find(defaultAchievementsUri) != std::string::npos - || uri.find(defaultNotificationUri) != std::string::npos) + if (uri.find(defaultAchievementsUri) != xsapi_internal_string::npos + || uri.find(defaultNotificationUri) != xsapi_internal_string::npos) { mockRtaService.CompleteSubscribeHandshake(n); } @@ -1557,10 +1557,10 @@ private: mock.SetResponseBody(response); // mock the response of Get Achievements auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { - if (uri.find(defaultAchievementsUri) != std::string::npos - || uri.find(defaultNotificationUri) != std::string::npos) + if (uri.find(defaultAchievementsUri) != xsapi_internal_string::npos + || uri.find(defaultNotificationUri) != xsapi_internal_string::npos) { mockRtaService.CompleteSubscribeHandshake(n); } @@ -1775,14 +1775,15 @@ private: xuid, willUnlock ] - (HttpMock* mock, std::string requestUrl, std::string requestBody) + (HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestBody); UNREFERENCED_PARAMETER(requestUrl); - std::stringstream uri; - uri << "https://achievements.xboxlive.com/users/xuid(" << xuid << ")/achievements/" << AppConfig::Instance()->Scid(); + xsapi_internal_stringstream uri; + uri << "https://achievements.xboxlive.com/users/xuid(" << xuid << ")/achievements/" << utils::ToLower(AppConfig::Instance()->Scid()); + auto& mockRtaService{ MockRealTimeActivityService::Instance() }; mockRtaService.RaiseEvent(uri.str(), progressPayload.c_str()); }); @@ -1872,7 +1873,7 @@ private: 100 ); VERIFY_IS_TRUE( - utils::TimeTFromDatetime(datetime::from_string(utils::string_t_from_internal_string(achievementUnlockTime), datetime::date_format::ISO_8601)) + utils::TimeTFromDatetime(datetime::from_string(achievementUnlockTime, datetime::date_format::ISO_8601)) == achievement->progression.timeUnlocked ); XblAchievementsManagerResultCloseHandle(resultHandle); @@ -2841,7 +2842,7 @@ public: 100 ); VERIFY_IS_TRUE( - utils::TimeTFromDatetime(datetime::from_string(utils::string_t_from_internal_string(achievementUnlockTime), datetime::date_format::ISO_8601)) + utils::TimeTFromDatetime(datetime::from_string(achievementUnlockTime, datetime::date_format::ISO_8601)) == achievement->progression.timeUnlocked ); XblAchievementsManagerResultCloseHandle(resultHandle); @@ -3017,7 +3018,7 @@ public: ); } VERIFY_IS_TRUE( - utils::TimeTFromDatetime(datetime::from_string(utils::string_t_from_internal_string(achievementUnlockTime), datetime::date_format::ISO_8601)) + utils::TimeTFromDatetime(datetime::from_string(achievementUnlockTime, datetime::date_format::ISO_8601)) == achievement->progression.timeUnlocked ); XblAchievementsManagerResultCloseHandle(resultHandle); diff --git a/Tests/UnitTests/Tests/Services/AchievementsTests.cpp b/Tests/UnitTests/Tests/Services/AchievementsTests.cpp index c48afa1d..55a79bd3 100644 --- a/Tests/UnitTests/Tests/Services/AchievementsTests.cpp +++ b/Tests/UnitTests/Tests/Services/AchievementsTests.cpp @@ -215,14 +215,14 @@ public: auto xboxLiveContext = env.CreateMockXboxLiveContext(); xsapi_internal_stringstream url; - url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/MockScid/update"; + url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/mockscid/update"; HttpMock mock("POST", url.str(), 304 ); bool requestWellFormed{ true }; - mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); - auto expectedRequest = R"({"action":"progressUpdate","serviceConfigId":"MockScid","titleId":1234,"userId":"101010101010","achievements":[{"id":"1","percentComplete":100}]})"; + auto expectedRequest = R"({"action":"progressUpdate","serviceConfigId":"mockscid","titleId":1234,"userId":"101010101010","achievements":[{"id":"1","percentComplete":100}]})"; requestWellFormed &= (requestBody == expectedRequest); }); @@ -249,7 +249,7 @@ public: responseJson.Parse(defaultAchievementResponse); xsapi_internal_stringstream url; - url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/serviceConfigurationId/achievementId"; + url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/serviceconfigurationid/achievementId"; HttpMock mock("POST", url.str(), 200, responseJson); JsonValue& achievementToVerify = responseJson["achievements"][0]; @@ -272,7 +272,7 @@ public: responseJson.Parse(defaultAchievementResponse); xsapi_internal_stringstream url; - url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/serviceConfigurationId/achievementId"; + url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/serviceconfigurationid/achievementId"; HttpMock mock("POST", url.str(), 404); JsonValue& achievementToVerify = responseJson["achievements"][0]; @@ -296,7 +296,7 @@ public: url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements?titleId=1234&maxItems=100"; HttpMock mock("GET", url.str(), 200, responseJson); bool requestWellFormed{ true }; - mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -337,7 +337,7 @@ public: url << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements?titleId=1234&maxItems=100"; HttpMock mock("GET", url.str(), 200, responseJson); bool requestWellFormed{ true }; - mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + mock.SetMockMatchedCallback([&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -490,11 +490,11 @@ public: auto xboxLiveContext = env.CreateMockXboxLiveContext(); auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { - std::stringstream expectedUri; + xsapi_internal_stringstream expectedUri; expectedUri << "https://achievements.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/achievements/" << AppConfig::Instance()->Scid(); - VERIFY_ARE_EQUAL_STR(uri, expectedUri.str()); + VERIFY_ARE_EQUAL_STR_IGNORE_CASE(uri.data(), expectedUri.str().data()); mockRtaService.CompleteSubscribeHandshake(n); diff --git a/Tests/UnitTests/Tests/Services/MatchmakingTests.cpp b/Tests/UnitTests/Tests/Services/MatchmakingTests.cpp index 4d5147dc..1fed276b 100644 --- a/Tests/UnitTests/Tests/Services/MatchmakingTests.cpp +++ b/Tests/UnitTests/Tests/Services/MatchmakingTests.cpp @@ -117,7 +117,7 @@ public: bool requestWellFormed { true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string body) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); @@ -173,7 +173,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string body) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); diff --git a/Tests/UnitTests/Tests/Services/MultiplayerActivityTests.cpp b/Tests/UnitTests/Tests/Services/MultiplayerActivityTests.cpp index 2b26e5a7..e2365021 100644 --- a/Tests/UnitTests/Tests/Services/MultiplayerActivityTests.cpp +++ b/Tests/UnitTests/Tests/Services/MultiplayerActivityTests.cpp @@ -69,7 +69,7 @@ public: HttpMock mock{ "POST", url.str(), 204 }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { rapidjson::Document d; d.Parse(body.data()); @@ -108,7 +108,7 @@ public: HttpMock mock{ "POST", url.str(), 204 }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { httpRequestCount++; @@ -185,7 +185,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { JsonDocument d; d.Parse(body.data()); @@ -272,7 +272,7 @@ public: uint64_t xuids[] = { 1, 2 }; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { JsonDocument b; b.Parse(body.data()); @@ -320,7 +320,7 @@ public: uint64_t xuids[] = { 1, 2 }; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { JsonDocument b; b.Parse(body.data()); @@ -397,7 +397,7 @@ public: bool requestWellFormed{ false }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*url*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*url*/, xsapi_internal_string body) { requestWellFormed = VerifyJson(expectedRequestBody, body.data()); }); diff --git a/Tests/UnitTests/Tests/Services/MultiplayerManagerTests.cpp b/Tests/UnitTests/Tests/Services/MultiplayerManagerTests.cpp index 4346df99..ca038a2f 100644 --- a/Tests/UnitTests/Tests/Services/MultiplayerManagerTests.cpp +++ b/Tests/UnitTests/Tests/Services/MultiplayerManagerTests.cpp @@ -2864,9 +2864,9 @@ public: MPMTestEnvironment() noexcept { auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { - if (uri.find("sessiondirectory") != std::string::npos) + if (uri.find("sessiondirectory") != xsapi_internal_string::npos) { mockRtaService.CompleteSubscribeHandshake(n, rtaConnectionId); } @@ -5137,7 +5137,7 @@ public: mock.SetResponseBody(getResponses[0]); mock.SetResponseHttpStatus(getStatuses[0]); mock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - mock.SetMockMatchedCallback([getResponses, getStatuses, &mockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + mock.SetMockMatchedCallback([getResponses, getStatuses, &mockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (mockCount < getResponses.size()) { @@ -5307,7 +5307,7 @@ public: HttpMock mock(POST, defaultMpsdUri, 201); mock.SetResponseBody(writeResponses[0]); mock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - mock.SetMockMatchedCallback([writeResponses, &mockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + mock.SetMockMatchedCallback([writeResponses, &mockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (mockCount < writeResponses.size()) { @@ -5916,7 +5916,7 @@ public: HttpMock lobbyMock(GET, defaultMpsdUri, 200); lobbyMock.SetResponseBody(lobbyResponses[0]); lobbyMock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (lobbyMockCount < lobbyResponses.size()) { @@ -5929,7 +5929,7 @@ public: HttpMock gameMock(GET, defaultGameUri, 200); gameMock.SetResponseBody(gameResponses[0]); gameMock.SetResponseHeaders(defaultGameHttpResponseHeaders); - gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (gameMockCount < gameResponses.size()) { @@ -6096,7 +6096,7 @@ public: HttpMock lobbyMock(GET, defaultMpsdUri, 200); lobbyMock.SetResponseBody(lobbyResponses[0]); lobbyMock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (lobbyMockCount < lobbyResponses.size()) { @@ -6109,7 +6109,7 @@ public: HttpMock gameMock(GET, defaultGameUri, 200); gameMock.SetResponseBody(gameResponses[0]); gameMock.SetResponseHeaders(defaultGameHttpResponseHeaders); - gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (gameMockCount < gameResponses.size()) { @@ -6302,7 +6302,7 @@ public: uint32_t lobbyMockCount{ 0 }; HttpMock lobbyMock(GET, defaultMpsdUri, 200); lobbyMock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (lobbyMockCount < lobbyResponses.size()) { @@ -6314,7 +6314,7 @@ public: uint32_t gameMockCount{ 0 }; HttpMock gameMock(GET, defaultGameUri, 200); gameMock.SetResponseHeaders(defaultGameHttpResponseHeaders); - gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (gameMockCount < gameResponses.size()) { @@ -6452,7 +6452,7 @@ public: HttpMock lobbyMock(GET, defaultMpsdUri, 200); lobbyMock.SetResponseBody(lobbyResponses[0]); lobbyMock.SetResponseHeaders(defaultLobbyHttpResponseHeaders); - lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + lobbyMock.SetMockMatchedCallback([lobbyResponses, &lobbyMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (lobbyMockCount < lobbyResponses.size()) { @@ -6465,7 +6465,7 @@ public: HttpMock gameMock(GET, defaultGameUri, 200); gameMock.SetResponseBody(gameResponses[0]); gameMock.SetResponseHeaders(defaultGameHttpResponseHeaders); - gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, std::string actualRequestUrl, std::string requestBody) + gameMock.SetMockMatchedCallback([gameResponses, &gameMockCount](class HttpMock* matchedMock, xsapi_internal_string actualRequestUrl, xsapi_internal_string requestBody) { if (gameMockCount < gameResponses.size()) { @@ -6573,7 +6573,7 @@ public: // Wait for MPM to refresh the lobby Event e; - mock.SetMockMatchedCallback([&](HttpMock*, std::string, std::string) + mock.SetMockMatchedCallback([&](HttpMock*, xsapi_internal_string, xsapi_internal_string) { e.Set(); }); diff --git a/Tests/UnitTests/Tests/Services/MultiplayerTests.cpp b/Tests/UnitTests/Tests/Services/MultiplayerTests.cpp index 0142a123..3bcb771b 100644 --- a/Tests/UnitTests/Tests/Services/MultiplayerTests.cpp +++ b/Tests/UnitTests/Tests/Services/MultiplayerTests.cpp @@ -11,6 +11,13 @@ using xbox::services::multiplayer::Serializers; +static xsapi_internal_string StringFromUint64Internal(_In_ uint64_t val) +{ + xsapi_internal_stringstream ss; + ss << val; + return ss.str(); +} + NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN #define MPSD_URI "https://sessiondirectory.xboxlive.com" @@ -97,7 +104,7 @@ public: MPTestEnv() noexcept : m_baseMock{ "", "" } { m_baseMock.SetMockMatchedCallback( - [](HttpMock* /*mock*/, std::string uri, std::string /*body*/) + [](HttpMock* /*mock*/, xsapi_internal_string uri, xsapi_internal_string /*body*/) { LOGS_DEBUG << "Unmocked HttpCall, uri=" << uri; assert(false); @@ -183,7 +190,7 @@ public: static MultiplayerSession Get( XblContextHandle xboxLiveContext, - const std::string& handleId, + const xsapi_internal_string& handleId, const JsonValue& response = MultiplayerTests::defaultSessionJson ) noexcept { @@ -228,7 +235,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { requestWellFormed &= VerifyJson(expectedRequestBody, body.data()); } @@ -416,7 +423,7 @@ public: const auto& mutableSettingsArray{ roleTypeJson["mutableRoleSettings"].GetArray() }; for (auto& setting : mutableSettingsArray) { - std::string settingString{ setting.GetString() }; + xsapi_internal_string settingString{ setting.GetString() }; if (settingString == "max") { expectedMutableSettings |= XblMutableRoleSettings::Max; @@ -535,7 +542,7 @@ public: if (p.KeywordCount) { - std::unordered_set actualKeywords(p.Keywords, p.Keywords + p.KeywordCount); + std::unordered_set actualKeywords(p.Keywords, p.Keywords + p.KeywordCount); const auto& expectedKeywords = systemJson["keywords"].GetArray(); VERIFY_ARE_EQUAL_UINT(expectedKeywords.Size(), actualKeywords.size()); for (auto& keyword : expectedKeywords) @@ -573,7 +580,7 @@ public: if (p.ServerConnectionStringCandidatesCount) { - std::unordered_set actualServerCandidates(p.ServerConnectionStringCandidates, p.ServerConnectionStringCandidates + p.ServerConnectionStringCandidatesCount); + std::unordered_set actualServerCandidates(p.ServerConnectionStringCandidates, p.ServerConnectionStringCandidates + p.ServerConnectionStringCandidatesCount); const auto& expectedServerCandidates{ systemJson["serverConnectionStringCandidates"].GetArray() }; VERIFY_ARE_EQUAL_UINT(expectedServerCandidates.Size(), actualServerCandidates.size()); for (auto& candidate : expectedServerCandidates) @@ -636,7 +643,7 @@ public: for (auto iter = json.MemberBegin(); iter != json.MemberEnd(); ++iter) { - if (std::string{ iter->name.GetString() } == "me") + if (xsapi_internal_string{ iter->name.GetString() } == "me") { VERIFY_ARE_EQUAL_UINT(1u, members.size()); VerifyMember(*members.begin()->second, iter->value); @@ -800,7 +807,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); @@ -849,7 +856,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string body) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); @@ -1039,12 +1046,12 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string body) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); bool batch{ query->XuidFiltersCount > 1 }; - std::stringstream expectedPath; + xsapi_internal_stringstream expectedPath; expectedPath << "/serviceconfigs/" << query->Scid << "/sessiontemplates/" << query->SessionTemplateNameFilter; if (batch) { @@ -1079,7 +1086,7 @@ public: } if (query->ContractVersionFilter) { - requestWellFormed &= queryParams["version"] == Utils::StringFromUint64(query->ContractVersionFilter); + requestWellFormed &= queryParams["version"] == StringFromUint64Internal(query->ContractVersionFilter); } switch (query->VisibilityFilter) { @@ -1133,7 +1140,7 @@ public: requestWellFormed &= body.empty(); if (query->XuidFiltersCount == 1) { - requestWellFormed &= queryParams["xuid"] == Utils::StringFromUint64(query->XuidFilters[0]); + requestWellFormed &= queryParams["xuid"] == StringFromUint64Internal(query->XuidFilters[0]); } } } @@ -1865,16 +1872,16 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); auto roles{ session.RoleTypes() }; for (const auto& roleType : roles) { - if (std::string{ roleType->Name } == "lfg") + if (xsapi_internal_string{ roleType->Name } == "lfg") { for (size_t i = 0; i < roleType->RoleCount; ++i) { - if (std::string{ roleType->Roles[i].Name } == "friend") + if (xsapi_internal_string{ roleType->Roles[i].Name } == "friend") { VERIFY_ARE_EQUAL_UINT(max, roleType->Roles[i].MaxMemberCount); VERIFY_ARE_EQUAL_UINT(target, roleType->Roles[i].TargetCount); } - else if (std::string{ roleType->Roles[i].Name } == "other") + else if (xsapi_internal_string{ roleType->Roles[i].Name } == "other") { VERIFY_ARE_EQUAL_UINT(max, roleType->Roles[i].MaxMemberCount); } @@ -1892,7 +1899,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock*, std::string, std::string body) + [&](HttpMock*, xsapi_internal_string, xsapi_internal_string body) { requestWellFormed &= VerifyJson(testJson["activityJson"], body.data()); }); @@ -1936,7 +1943,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock*, std::string, std::string body) + [&](HttpMock*, xsapi_internal_string, xsapi_internal_string body) { requestWellFormed &= VerifyJson(testJson["transferHandleJson"], body.data()); }); @@ -2042,32 +2049,31 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); size_t requestCount{ 0 }; bool requestsWellFormed{ true }; const char* responseIds[] = { "B8704EC5-95CD-408B-BD41-BAA7A2761CC2", "9D74C42E-87DE-47BA-B489-D3A264C9F994" }; - const auto& expectedRequestBodyTemplate{ testJson["inviteRequestJson"] }; - const auto& responseBodyTemplate{ testJson["inviteResponseJson"] }; + JsonDocument testResponses{ GetTestResponses("TestResponses\\Multiplayer.json") }; + auto inviteRequestJson = JsonUtils::SerializeJson(testResponses["inviteRequestJson"]); + auto inviteResponseJson = JsonUtils::SerializeJson(testResponses["inviteResponseJson"]); + JsonDocument expectedRequestBodyJson; + JsonDocument responseBodyJson; + expectedRequestBodyJson.Parse(inviteRequestJson.c_str()); + responseBodyJson.Parse(inviteResponseJson.c_str()); mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string uri, std::string body) + [&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(uri); if (requestCount < xuids.size()) { { - JsonDocument expectedRequest; - auto& a{ expectedRequest.GetAllocator() }; - expectedRequest.CopyFrom(expectedRequestBodyTemplate, a, false); - JsonUtils::SetMember(expectedRequest, "invitedXuid", JsonValue{ Utils::StringFromUint64(xuids[requestCount]).data(), a }); - - requestsWellFormed &= VerifyJson(expectedRequest, body.data()); + auto& a{ expectedRequestBodyJson.GetAllocator() }; + JsonUtils::SetMember(expectedRequestBodyJson, "invitedXuid", JsonValue{ StringFromUint64Internal(xuids[requestCount]).data(), a }); + requestsWellFormed &= VerifyJson(expectedRequestBodyJson, body.data()); } { - JsonDocument response; - auto& a{ response.GetAllocator() }; - response.CopyFrom(responseBodyTemplate, a, false); - JsonUtils::SetMember(response, "invitedXuid", JsonValue{ Utils::StringFromUint64(xuids[requestCount]).data(), a }); - JsonUtils::SetMember(response, "id", JsonValue{ responseIds[requestCount], a }); - - mock->SetResponseBody(response); + auto& a{ responseBodyJson.GetAllocator() }; + JsonUtils::SetMember(responseBodyJson, "invitedXuid", JsonValue{ StringFromUint64Internal(xuids[requestCount]).data(), a }); + JsonUtils::SetMember(responseBodyJson, "id", JsonValue{ responseIds[requestCount], a }); + mock->SetResponseBody(responseBodyJson); } } requestCount++; @@ -2112,7 +2118,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); mock.SetResponseBody(testJson["activitiesForUserResponseJson"]); bool requestWellFormed{ true }; - mock.SetMockMatchedCallback([&](HttpMock* mock, std::string uri, std::string body) + mock.SetMockMatchedCallback([&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); @@ -2186,7 +2192,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); mock.SetResponseBody(testJson["activitiesForSocialGroupResponseJson"]); bool requestWellFormed{ true }; - mock.SetMockMatchedCallback([&](HttpMock* mock, std::string uri, std::string body) + mock.SetMockMatchedCallback([&](HttpMock* mock, xsapi_internal_string uri, xsapi_internal_string body) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(uri); @@ -2371,7 +2377,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); MPTestEnv env{}; auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (uri == MPSD_RTA_URI) { @@ -2406,7 +2412,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); [&](const XblMultiplayerSessionChangeEventArgs& args) { const auto& tap{ rtaUpdateJson["shoulderTaps"].GetArray()[0] }; - auto resourceSplit{ utils::string_split(tap["resource"].GetString(), '~') }; + auto resourceSplit{ utils::string_split_internal(tap["resource"].GetString(), '~') }; VERIFY_ARE_EQUAL_STR(resourceSplit[0], args.SessionReference.Scid); VERIFY_ARE_EQUAL_STR(resourceSplit[1], args.SessionReference.SessionTemplateName); @@ -2437,7 +2443,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); // Auto confirm subscriptions auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (uri == MPSD_RTA_URI) { @@ -2486,7 +2492,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* /*mock*/, std::string /*uri*/, std::string body) + [&](HttpMock* /*mock*/, xsapi_internal_string /*uri*/, xsapi_internal_string body) { // Skip verification of the subId since its a random GUID JsonDocument bodyJson; @@ -2553,16 +2559,7 @@ session.Write(testJson["serverConnectionStringCandidatesJson"]); VERIFY_SUCCEEDED(XblMultiplayerGetSessionAsync(env.XboxLiveContext(), &ref, &async)); auto hr = XAsyncGetStatus(&async, true); - VERIFY_ARE_EQUAL(S_OK, hr); - - XblMultiplayerSessionHandle sessionHandle{ nullptr }; - XblMultiplayerGetSessionResult(&async, &sessionHandle); - VERIFY_ARE_EQUAL(S_OK, hr); - - if (sessionHandle) - { - XblMultiplayerSessionCloseHandle(sessionHandle); - } + VERIFY_ARE_EQUAL(__HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND), hr); } } diff --git a/Tests/UnitTests/Tests/Services/PresenceTests.cpp b/Tests/UnitTests/Tests/Services/PresenceTests.cpp index 6db1e20b..ede600af 100644 --- a/Tests/UnitTests/Tests/Services/PresenceTests.cpp +++ b/Tests/UnitTests/Tests/Services/PresenceTests.cpp @@ -181,7 +181,7 @@ public: void VerifyBroadcastRecord(XblPresenceBroadcastRecord* broadcastRecord, JsonValue resultToVerify) { const char* provider = broadcastRecord->provider == XblPresenceBroadcastProvider::Twitch ? "twitch" : "unknown"; - xbox::services::string_t resultStr = Utils::StringTFromUtf8(resultToVerify["started"].GetString()); + xsapi_internal_string resultStr = resultToVerify["started"].GetString(); xbox::services::datetime resultDatetime = xbox::services::datetime::from_string(resultStr, xbox::services::datetime::date_format::ISO_8601); VERIFY_ARE_EQUAL_STR(provider, resultToVerify["provider"].GetString()); @@ -193,9 +193,9 @@ public: void VerifyPresenceTitleRecord(XblPresenceTitleRecord* record, JsonValue resultToVerify) { - xbox::services::string_t resultStr = Utils::StringTFromUtf8(resultToVerify["lastModified"].GetString()); + xsapi_internal_string resultStr = resultToVerify["lastModified"].GetString(); xbox::services::datetime resultDatetime = xbox::services::datetime::from_string(resultStr, xbox::services::datetime::date_format::ISO_8601); - string_t expectedStr = utils::DatetimeFromTimeT(record->lastModified).to_string(xbox::services::datetime::date_format::ISO_8601); + xsapi_internal_string expectedStr = utils::DatetimeFromTimeT(record->lastModified).to_string(xbox::services::datetime::date_format::ISO_8601); UNREFERENCED_PARAMETER(expectedStr); VERIFY_ARE_EQUAL_INT(record->titleId, std::stoi(resultToVerify["id"].GetString())); VERIFY_ARE_EQUAL_STR(record->titleName, resultToVerify["name"].GetString()); @@ -328,13 +328,13 @@ public: } std::shared_ptr CreatePresenceMock( - std::string titleId + xsapi_internal_string titleId ) { auto presenceMock = std::make_shared("GET", "https://userpresence.xboxlive.com"); presenceMock->SetMockMatchedCallback( - [titleId](HttpMock* mock, std::string requestUrl, std::string requestBody) + [titleId](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(requestUrl); @@ -371,7 +371,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -428,7 +428,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -474,7 +474,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -543,7 +543,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -613,7 +613,7 @@ public: const uint32_t titleId = 1563044810; const char titlePresenceUri[]{ "https://userpresence.xboxlive.com/users/xuid(1234)/titles/1563044810" }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (uri == titlePresenceUri) { @@ -676,9 +676,9 @@ public: auto& mockRtaService{ MockRealTimeActivityService::Instance() }; const uint64_t xuid = 1234; - const std::string devicePresenceUri{ "https://userpresence.xboxlive.com/users/xuid(1234)/devices" }; + const xsapi_internal_string devicePresenceUri{ "https://userpresence.xboxlive.com/users/xuid(1234)/devices" }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (uri == devicePresenceUri) { @@ -698,7 +698,7 @@ public: JsonDocument deviceResponseJson{}; deviceResponseJson.Parse(devicePresenceResponse); - auto response = utils::string_split(deviceResponseJson.GetString(), ':'); + auto response = utils::string_split_internal(deviceResponseJson.GetString(), ':'); VERIFY_ARE_EQUAL_INT(xuid, handler.xuid); VERIFY_IS_TRUE(xbox::services::presence::DeviceRecord::DeviceTypeFromString(response[0]) == handler.deviceType); VERIFY_ARE_EQUAL(response[1] == "true", handler.isUserLoggedOnDevice); @@ -715,7 +715,7 @@ public: const uint64_t xuid2{ 2 }; std::map subAddedEvents; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRtaService.CompleteSubscribeHandshake(n, defaultPresenceResponse); @@ -753,7 +753,7 @@ public: auto& mockRtaService{ MockRealTimeActivityService::Instance() }; uint32_t subCount{ 0 }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRtaService.CompleteSubscribeHandshake(n, defaultPresenceResponse); subCount++; diff --git a/Tests/UnitTests/Tests/Services/PrivacyTests.cpp b/Tests/UnitTests/Tests/Services/PrivacyTests.cpp index 75325ec3..a771f4ce 100644 --- a/Tests/UnitTests/Tests/Services/PrivacyTests.cpp +++ b/Tests/UnitTests/Tests/Services/PrivacyTests.cpp @@ -85,7 +85,7 @@ public: [ &xuids ] - (HttpMock* mock, std::string requestUrl, std::string requestBody) + (HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(requestUrl); VERIFY_IS_TRUE(requestBody.empty()); diff --git a/Tests/UnitTests/Tests/Services/ProfileTests.cpp b/Tests/UnitTests/Tests/Services/ProfileTests.cpp index bd1c71e0..ee8b189f 100644 --- a/Tests/UnitTests/Tests/Services/ProfileTests.cpp +++ b/Tests/UnitTests/Tests/Services/ProfileTests.cpp @@ -164,8 +164,8 @@ public: // Validate that a batch request is well formed bool VerifyBatchRequest( - _In_ const std::string& requestUri, - _In_ const std::string& requestBody, + _In_ const xsapi_internal_string& requestUri, + _In_ const xsapi_internal_string& requestBody, _In_ const std::vector& requestedXuids ) { @@ -201,7 +201,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock*, std::string requestUrl, std::string requestBody) + [&](HttpMock*, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { // XblProfileGetUserProfileResult just makes a batch request with 1 xuid requestWellFormed = VerifyBatchRequest(requestUrl, requestBody, std::vector{ expectedProfile.xuid }); @@ -235,7 +235,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock*, std::string requestUrl, std::string requestBody) + [&](HttpMock*, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { requestWellFormed = VerifyBatchRequest(requestUrl, requestBody, xuids); } @@ -277,9 +277,9 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock*, std::string requestUri, std::string requestBody) + [&](HttpMock*, xsapi_internal_string requestUri, xsapi_internal_string requestBody) { - std::stringstream expectedUri; + xsapi_internal_stringstream expectedUri; expectedUri << "https://profile.xboxlive.com/users/me/profile/settings/people/"; expectedUri << socialGroup; expectedUri << "?settings=AppDisplayName,AppDisplayPicRaw,GameDisplayName,GameDisplayPicRaw,Gamerscore,Gamertag,ModernGamertag,ModernGamertagSuffix,UniqueModernGamertag"; diff --git a/Tests/UnitTests/Tests/Services/RealTimeActivityManagerTests.cpp b/Tests/UnitTests/Tests/Services/RealTimeActivityManagerTests.cpp index 702e2530..43adaf61 100644 --- a/Tests/UnitTests/Tests/Services/RealTimeActivityManagerTests.cpp +++ b/Tests/UnitTests/Tests/Services/RealTimeActivityManagerTests.cpp @@ -103,7 +103,7 @@ public: auto& mockRta{ MockRealTimeActivityService::Instance() }; Event completeSubscribeHandshake; - mockRta.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRta.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { completeSubscribeHandshake.Wait(); mockRta.CompleteSubscribeHandshake(n); @@ -142,7 +142,7 @@ public: auto xboxLiveContext = env.CreateMockXboxLiveContext(); auto& mockRta{ MockRealTimeActivityService::Instance() }; - mockRta.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRta.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRta.CompleteSubscribeHandshake(n); }); @@ -262,7 +262,7 @@ public: auto rtaManager{ GlobalState::Get()->RTAManager() }; auto& mockRta{ MockRealTimeActivityService::Instance() }; - mockRta.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRta.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRta.CompleteSubscribeHandshake(n); }); @@ -300,7 +300,7 @@ public: auto rtaManager{ GlobalState::Get()->RTAManager() }; auto& mockRta{ MockRealTimeActivityService::Instance() }; - mockRta.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRta.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRta.CompleteSubscribeHandshake(n); }); @@ -331,7 +331,7 @@ public: auto& mockRta{ MockRealTimeActivityService::Instance() }; uint8_t subscribeAttempts{ 0 }; - mockRta.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRta.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (subscribeAttempts++ == 0) { diff --git a/Tests/UnitTests/Tests/Services/ReputationTests.cpp b/Tests/UnitTests/Tests/Services/ReputationTests.cpp index 7f32a8ee..cd9ed3d1 100644 --- a/Tests/UnitTests/Tests/Services/ReputationTests.cpp +++ b/Tests/UnitTests/Tests/Services/ReputationTests.cpp @@ -56,7 +56,7 @@ public: bool requestWellFormed{ true }; reputationMock.SetMockMatchedCallback( - [&](HttpMock*, std::string url, std::string requestBody) + [&](HttpMock*, xsapi_internal_string url, xsapi_internal_string requestBody) { requestWellFormed &= url == "https://reputation.xboxlive.com/users/xuid(1)/feedback"; @@ -108,7 +108,7 @@ public: bool requestWellFormed{ true }; reputationMock.SetMockMatchedCallback( - [&](HttpMock*, std::string url, std::string requestBody) + [&](HttpMock*, xsapi_internal_string url, xsapi_internal_string requestBody) { requestWellFormed &= url == "https://reputation.xboxlive.com/users/xuid(1)/feedback"; @@ -148,7 +148,7 @@ public: bool requestWellFormed{ true }; reputationMock.SetMockMatchedCallback( - [&](HttpMock*, std::string url, std::string requestBody) + [&](HttpMock*, xsapi_internal_string url, xsapi_internal_string requestBody) { requestWellFormed &= url == "https://reputation.xboxlive.com/users/batchtitlefeedback"; JsonDocument expectedBodyJson; @@ -198,7 +198,7 @@ public: bool requestWellFormed{ true }; reputationMock.SetMockMatchedCallback( - [&](HttpMock*, std::string url, std::string requestBody) + [&](HttpMock*, xsapi_internal_string url, xsapi_internal_string requestBody) { requestWellFormed &= url == "https://reputation.xboxlive.com/users/batchtitlefeedback"; JsonDocument expectedBodyJson; diff --git a/Tests/UnitTests/Tests/Services/SocialManagerTests.cpp b/Tests/UnitTests/Tests/Services/SocialManagerTests.cpp index 1582a8dd..f75207f9 100644 --- a/Tests/UnitTests/Tests/Services/SocialManagerTests.cpp +++ b/Tests/UnitTests/Tests/Services/SocialManagerTests.cpp @@ -154,14 +154,14 @@ private: RTASubResponder(size_t followeeCount) { auto& rtaService{ system::MockRealTimeActivityService::Instance() }; - rtaService.SetSubscribeHandler([=](uint32_t n, std::string uri) + rtaService.SetSubscribeHandler([=](uint32_t n, xsapi_internal_string uri) { SMTestEnvironment::RTASubscribeHandler(n, uri); - if (uri.find("https://userpresence.xboxlive.com") != std::string::npos) + if (uri.find("https://userpresence.xboxlive.com") != xsapi_internal_string::npos) { ++presenceSubsComplete; } - else if (uri.find("http://social.xboxlive.com") != std::string::npos) + else if (uri.find("http://social.xboxlive.com") != xsapi_internal_string::npos) { socialRelationshipSubComplete = true; } @@ -274,7 +274,7 @@ private: isFavorite, isFollowedByCaller ] - (HttpMock* mock, std::string requestUrl, std::string requestBody) + (HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { std::vector xuids; @@ -326,7 +326,7 @@ private: offlineXuids = std::unordered_set{ offlineXuids.begin(), offlineXuids.end() }, titleId ] - (HttpMock* mock, std::string requestUrl, std::string requestBody) mutable + (HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) mutable { SetPresenceResponse(mock, requestUrl, requestBody, std::move(offlineXuids), titleId); }); @@ -339,7 +339,7 @@ private: { for (auto xuid : userList) { - std::stringstream uri; + xsapi_internal_stringstream uri; uri << "https://userpresence.xboxlive.com/users/xuid(" << xuid << ")/devices"; MockRealTimeActivityService::Instance().RaiseEvent(uri.str(), online ? R"("PC:true")" : R"("PC:false")"); @@ -353,7 +353,7 @@ private: { for (auto xuid : userList) { - std::stringstream uri; + xsapi_internal_stringstream uri; uri << "https://userpresence.xboxlive.com/users/xuid(" << xuid << ")/titles/1234"; MockRealTimeActivityService::Instance().RaiseEvent(uri.str(), ended ? R"("ended")" : R"("started")"); @@ -366,7 +366,7 @@ private: uint64_t affectedXuid ) const noexcept { - std::stringstream uri; + xsapi_internal_stringstream uri; uri << "http://social.xboxlive.com/users/xuid(" << localUser.Xuid() << ")/friends"; rapidjson::Document eventData{ rapidjson::kObjectType }; @@ -384,14 +384,14 @@ private: std::vector FollowedXuids; private: - static void RTASubscribeHandler(uint32_t n, std::string uri) + static void RTASubscribeHandler(uint32_t n, xsapi_internal_string uri) { auto& rtaService{ system::MockRealTimeActivityService::Instance() }; - if (uri.find("https://userpresence.xboxlive.com") != std::string::npos) + if (uri.find("https://userpresence.xboxlive.com") != xsapi_internal_string::npos) { rtaService.CompleteSubscribeHandshake(n, presenceOnlineRtaMessageSubscribeComplete); } - else if (uri.find("http://social.xboxlive.com") != std::string::npos) + else if (uri.find("http://social.xboxlive.com") != xsapi_internal_string::npos) { rtaService.CompleteSubscribeHandshake(n); } @@ -399,14 +399,14 @@ private: static size_t SetPresenceResponse( HttpMock* mock, - const std::string& requestUrl, - const std::string& requestBody, + const xsapi_internal_string& requestUrl, + const xsapi_internal_string& requestBody, std::unordered_set&& offlineXuids = {}, uint32_t titleId = MOCK_TITLEID ) { JsonDocument userArr{}; - if (requestUrl.find("batch") != std::string::npos) + if (requestUrl.find("batch") != xsapi_internal_string::npos) { // for batch requests the user list is in the request body JsonDocument jsonRequest{ rapidjson::kObjectType }; @@ -452,7 +452,7 @@ private: const std::vector& events ) const noexcept { - static std::unordered_map eventTypesMap + static std::unordered_map eventTypesMap { { XblSocialManagerEventType::UsersAddedToSocialGraph, "UsersAddedToSocialGraph" }, { XblSocialManagerEventType::UsersRemovedFromSocialGraph, "UsersRemovedFromSocialGraph" }, @@ -467,7 +467,7 @@ private: for (auto& event : events) { - std::stringstream ss; + xsapi_internal_stringstream ss; ss << "SocialManager Event: " << eventTypesMap[event->eventType] << std::endl; for (uint32_t i = 0; i < XBL_SOCIAL_MANAGER_MAX_AFFECTED_USERS_PER_EVENT; i++) { @@ -2013,7 +2013,7 @@ public: // title history tests VERIFY_IS_TRUE(user->title_history().has_user_played()); - VERIFY_IS_TRUE(Utils::TimeTFromDatetime(user->title_history().last_time_user_played()) == utils::TimeTFromDatetime(xbox::services::datetime::from_string(_T("2015-01-26T22:54:54.6630Z"), xbox::services::datetime::date_format::ISO_8601))); + VERIFY_IS_TRUE(Utils::TimeTFromDatetime(user->title_history().last_time_user_played()) == utils::TimeTFromDatetime(xbox::services::datetime::from_string("2015-01-26T22:54:54.6630Z", xbox::services::datetime::date_format::ISO_8601))); } auto destroyGroupResult = socialManager->destroy_social_user_group(group); diff --git a/Tests/UnitTests/Tests/Services/SocialTests.cpp b/Tests/UnitTests/Tests/Services/SocialTests.cpp index ee78bb5d..abea70a9 100644 --- a/Tests/UnitTests/Tests/Services/SocialTests.cpp +++ b/Tests/UnitTests/Tests/Services/SocialTests.cpp @@ -34,50 +34,50 @@ private: [ &people ] - (HttpMock* mock, std::string requestUrl, std::string requestBody) + (HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { assert(requestBody.empty()); - xbox::services::uri url(Utils::StringTFromUtf8(requestUrl.data()).data()); + xbox::services::uri url(requestUrl.data()); auto queryParams = url.split_query(url.query()); size_t startIndex{ 0 }; size_t maxItems{ people.size() }; - std::wstring view{ L"All" }; + xsapi_internal_string view{ "All" }; - if (queryParams.find(L"startIndex") != queryParams.end()) + if (queryParams.find("startIndex") != queryParams.end()) { - startIndex = Utils::Uint64FromStringT(queryParams[L"startIndex"]); + startIndex = _atoi64(queryParams["startIndex"].c_str()); } - if (queryParams.find(L"maxItems") != queryParams.end()) + if (queryParams.find("maxItems") != queryParams.end()) { - maxItems = Utils::Uint64FromStringT(queryParams[L"maxItems"]); + maxItems = _atoi64(queryParams["maxItems"].c_str()); } - if (queryParams.find(L"view") != queryParams.end()) + if (queryParams.find("view") != queryParams.end()) { - view = queryParams[L"view"]; + view = queryParams["view"]; } std::vector filteredPeople; std::copy_if(people.begin(), people.end(), std::back_inserter(filteredPeople), [&](const SocialRelationship& person) { - if (Utils::Stricmp(L"favorite", view) == 0) + if (_stricmp("favorite", view.c_str()) == 0) { return person.isFavorite; } - else if (Utils::Stricmp(L"LegacyXboxLiveFriends", view) == 0) + else if (_stricmp("LegacyXboxLiveFriends", view.c_str()) == 0) { auto iter = std::find_if(person.socialNetworks.begin(), person.socialNetworks.end(), [](const std::wstring& s) { - return Utils::Stricmp(s, L"LegacyXboxLive") == 0; + return _stricmp(convert::utf16_to_utf8(s).c_str(), "LegacyXboxLive") == 0; }); return iter != person.socialNetworks.end(); } else { - assert(Utils::Stricmp(L"All", view) == 0); + assert(_stricmp("All", view.c_str()) == 0); return true; } }); @@ -298,9 +298,9 @@ private: auto xboxLiveContext = env.CreateMockXboxLiveContext(); auto& mockRtaService{ MockRealTimeActivityService::Instance() }; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { - std::stringstream expectedUri; + xsapi_internal_stringstream expectedUri; expectedUri << "http://social.xboxlive.com/users/xuid(" << xboxLiveContext->Xuid() << ")/friends"; VERIFY_ARE_EQUAL_STR(uri, expectedUri.str()); @@ -393,7 +393,7 @@ private: xboxLiveContext->real_time_activity_service()->activate(); - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { mockRtaService.CompleteSubscribeHandshake(n); diff --git a/Tests/UnitTests/Tests/Services/StatsTests.cpp b/Tests/UnitTests/Tests/Services/StatsTests.cpp index 4e035882..5086de17 100644 --- a/Tests/UnitTests/Tests/Services/StatsTests.cpp +++ b/Tests/UnitTests/Tests/Services/StatsTests.cpp @@ -306,7 +306,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, xuids, scid, statNames](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, xuids, scid, statNames](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -374,7 +374,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, xuids, scid, statNames](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, xuids, scid, statNames](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -449,7 +449,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, xuids, requestedStats](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, xuids, requestedStats](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -527,7 +527,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, xuids, requestedStats](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, xuids, requestedStats](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -594,10 +594,10 @@ public: const uint32_t subId{ 321 }; const char* statName{ "Stat" }; - std::stringstream statsRtaUri; + xsapi_internal_stringstream statsRtaUri; statsRtaUri << statsServer << "/users/xuid(" << xuid << ")/scids/" << rtaScid << "/stats/" << statName; - mockRtaService.SetSubscribeHandler([&](uint32_t n, std::string uri) + mockRtaService.SetSubscribeHandler([&](uint32_t n, xsapi_internal_string uri) { if (uri == statsRtaUri.str()) { diff --git a/Tests/UnitTests/Tests/Services/StringVerifyTests.cpp b/Tests/UnitTests/Tests/Services/StringVerifyTests.cpp index 30d1b235..7762c453 100644 --- a/Tests/UnitTests/Tests/Services/StringVerifyTests.cpp +++ b/Tests/UnitTests/Tests/Services/StringVerifyTests.cpp @@ -42,7 +42,7 @@ public: auto requestStr = "xboxUserId"; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, requestStr](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, requestStr](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -81,7 +81,7 @@ public: auto requestStr = "xboxUserId"; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, requestStr](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, requestStr](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -123,7 +123,7 @@ public: const char* requestStrs[requestStrsCount]{ "asdf", "asdfasdf" }; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, requestStrs, requestStrsCount](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, requestStrs, requestStrsCount](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); @@ -175,7 +175,7 @@ public: const char* requestStrs[requestStrsCount]{ "asdf", "asdfasdf" }; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&requestWellFormed, requestStrs, requestStrsCount](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&requestWellFormed, requestStrs, requestStrsCount](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); UNREFERENCED_PARAMETER(requestUrl); diff --git a/Tests/UnitTests/Tests/Services/TitleManagedStatsTests.cpp b/Tests/UnitTests/Tests/Services/TitleManagedStatsTests.cpp index 35a2304f..94c407ab 100644 --- a/Tests/UnitTests/Tests/Services/TitleManagedStatsTests.cpp +++ b/Tests/UnitTests/Tests/Services/TitleManagedStatsTests.cpp @@ -116,7 +116,7 @@ private: [ &, expectedStatsJson ] - (HttpMock*, std::string requestUrl, std::string requestBody) + (HttpMock*, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { JsonDocument requestJson; requestJson.Parse(requestBody.data()); diff --git a/Tests/UnitTests/Tests/Services/TitleStorageTests.cpp b/Tests/UnitTests/Tests/Services/TitleStorageTests.cpp index c031d113..3b9bae5e 100644 --- a/Tests/UnitTests/Tests/Services/TitleStorageTests.cpp +++ b/Tests/UnitTests/Tests/Services/TitleStorageTests.cpp @@ -127,7 +127,7 @@ public: VERIFY_IS_TRUE(expected.IsObject()); String filename = expected["fileName"].GetString(); - auto tokens{ utils::string_split(filename, ',') }; + auto tokens{ utils::string_split_internal(filename, ',') }; VERIFY_ARE_EQUAL_UINT(2, tokens.size()); VERIFY_ARE_EQUAL_STR(tokens[0].data(), actual.blobPath); @@ -166,13 +166,13 @@ public: } } - std::string ExpectedUriPath( + xsapi_internal_string ExpectedUriPath( XblTitleStorageType storageType, uint64_t xuid, - const std::string& scid = MOCK_SCID + const xsapi_internal_string& scid = MOCK_SCID ) { - std::stringstream ss; + xsapi_internal_stringstream ss; switch (storageType) { case XblTitleStorageType::GlobalStorage: @@ -196,15 +196,15 @@ public: return ss.str(); } - std::string ExpectedUriPath( + xsapi_internal_string ExpectedUriPath( XblTitleStorageType storageType, uint64_t xuid, XblTitleStorageBlobType blobType, - const std::string& blobPath = "blobPath", - const std::string& scid = MOCK_SCID + const xsapi_internal_string& blobPath = "blobPath", + const xsapi_internal_string& scid = MOCK_SCID ) { - std::stringstream ss; + xsapi_internal_stringstream ss; ss << ExpectedUriPath(storageType, xuid, scid); ss << "/data/" << blobPath << ","; @@ -257,18 +257,18 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); requestWellFormed &= !requestBody.empty(); - auto queryParams = xbox::services::uri::split_query(xbox::services::uri{ Utils::StringTFromUtf8(requestUrl.data()) }.query()); + auto queryParams = xbox::services::uri::split_query(xbox::services::uri{ requestUrl.data() }.query()); - requestWellFormed &= queryParams[_T("clientFileTime")] == _T("Thu,%2001%20Jan%201970%2000:00:01%20GMT"); - requestWellFormed &= queryParams[_T("displayName")] == Utils::StringTFromUtf8(metadata.displayName); + requestWellFormed &= queryParams["clientFileTime"] == "Thu,%2001%20Jan%201970%2000:00:01%20GMT"; + requestWellFormed &= queryParams["displayName"] == metadata.displayName; if (blobType == XblTitleStorageBlobType::Binary) { - requestWellFormed &= queryParams[_T("finalBlock")] == _T("true"); + requestWellFormed &= queryParams["finalBlock"] == "true"; } } ); @@ -305,7 +305,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { requestWellFormed &= requestBody.empty(); requestWellFormed &= (HttpMock::GetUriPath(requestUrl) == ExpectedUriPath(storageType, xboxLiveContext->Xuid(), blobType)); @@ -404,7 +404,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); requestWellFormed &= requestBody.empty(); @@ -447,11 +447,11 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { requestWellFormed &= requestBody.empty(); - std::string expectedPath{ ExpectedUriPath(type, xboxLiveContext->Xuid()) }; + xsapi_internal_string expectedPath{ ExpectedUriPath(type, xboxLiveContext->Xuid()) }; expectedPath += "/data/blobPath"; requestWellFormed &= (HttpMock::GetUriPath(requestUrl) == expectedPath); @@ -507,7 +507,7 @@ public: bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(mock); requestWellFormed &= requestBody.empty(); @@ -705,23 +705,23 @@ public: uint32_t requestCount{ 0 }; bool requestWellFormed{ true }; mock.SetMockMatchedCallback( - [&](HttpMock* mock, std::string requestUrl, std::string requestBody) + [&](HttpMock* mock, xsapi_internal_string requestUrl, xsapi_internal_string requestBody) { UNREFERENCED_PARAMETER(requestBody); - auto queryParams = xbox::services::uri::split_query(xbox::services::uri{ Utils::StringTFromUtf8(requestUrl.data()) }.query()); - if (queryParams[_T("finalBlock")] == _T("true")) + auto queryParams = xbox::services::uri::split_query(xbox::services::uri{ requestUrl.data() }.query()); + if (queryParams["finalBlock"] == "true") { // Validate that we supplied the continuation token JsonDocument d; d.Parse(continuationTokenJson); - requestWellFormed &= d["continuationToken"].GetString() == Utils::StringFromStringT(queryParams[_T("continuationToken")]); + requestWellFormed &= d["continuationToken"].GetString() == queryParams["continuationToken"]; // no response body in this case mock->ClearReponseBody(); } - else if (queryParams[_T("finalBlock")] == _T("false")) + else if (queryParams["finalBlock"] == "false") { mock->SetResponseBody(continuationTokenJson); } diff --git a/Tests/UnitTests/Tests/Shared/LogTests.cpp b/Tests/UnitTests/Tests/Shared/LogTests.cpp index d25242d4..c75268ff 100644 --- a/Tests/UnitTests/Tests/Shared/LogTests.cpp +++ b/Tests/UnitTests/Tests/Shared/LogTests.cpp @@ -19,13 +19,13 @@ public: public: TestLogOutput() = default; - void write(_In_ HCTraceLevel level, _In_ const std::string& msg) override + void write(_In_ HCTraceLevel level, _In_ const xsapi_internal_string& msg) override { UNREFERENCED_PARAMETER(level); m_logOutput.push_back(msg); } - std::vector m_logOutput; + std::vector m_logOutput; }; DEFINE_TEST_CASE(WriteLog) @@ -57,9 +57,9 @@ public: VERIFY_ARE_EQUAL_INT(4, testOutput->m_logOutput.size()); VERIFY_ARE_EQUAL_STR(testLogText, testOutput->m_logOutput[0]); - VERIFY_ARE_EQUAL_STR(std::string{ testLogText } +"1", testOutput->m_logOutput[1]); - VERIFY_ARE_EQUAL_STR(std::string{ testLogText } +testLogText, testOutput->m_logOutput[2]); - VERIFY_ARE_EQUAL_STR(std::string{ testLogText } +veryverylong, testOutput->m_logOutput[3]); + VERIFY_ARE_EQUAL_STR(xsapi_internal_string{ testLogText } +"1", testOutput->m_logOutput[1]); + VERIFY_ARE_EQUAL_STR(xsapi_internal_string{ testLogText } +testLogText, testOutput->m_logOutput[2]); + VERIFY_ARE_EQUAL_STR(xsapi_internal_string{ testLogText } +veryverylong, testOutput->m_logOutput[3]); } DEFINE_TEST_CASE(WriteLogStream) @@ -77,7 +77,7 @@ public: VERIFY_ARE_EQUAL_INT(2, testOutput->m_logOutput.size()); VERIFY_ARE_EQUAL_STR(testLogText, testOutput->m_logOutput[0]); - VERIFY_ARE_EQUAL_STR(std::string{ testLogText } +"1", testOutput->m_logOutput[1]); + VERIFY_ARE_EQUAL_STR(xsapi_internal_string{ testLogText } +"1", testOutput->m_logOutput[1]); } DEFINE_TEST_CASE(WriteLogConcurrent) @@ -90,7 +90,7 @@ public: struct LogTask { - LogTask(std::shared_ptr logger, std::string message, size_t loopCount) noexcept + LogTask(std::shared_ptr logger, xsapi_internal_string message, size_t loopCount) noexcept : m_logger{ logger }, m_message{ std::move(message) }, m_loopCount{ loopCount } @@ -114,7 +114,7 @@ public: private: XAsyncBlock m_async{ nullptr, this }; std::shared_ptr m_logger; - std::string m_message; + xsapi_internal_string m_message; size_t m_loopCount; }; diff --git a/Utilities/CMake/CMakeLists.txt b/Utilities/CMake/CMakeLists.txt index 6c9f175b..77348e8a 100644 --- a/Utilities/CMake/CMakeLists.txt +++ b/Utilities/CMake/CMakeLists.txt @@ -203,20 +203,11 @@ else() endif() set(System_Source_Files - ../../Source/System/ppltasks_extra.h ../../Source/System/client_operation.h ../../Source/System/local_storage.h ../../Source/System/local_storage.cpp ) -if ( UNITTEST OR UWP OR PCWIN32 OR GDK ) - list(APPEND - System_Source_Files - ../../Source/System/auth_config.cpp - ../../Source/System/auth_config.h - ) -endif() - if( UNITTEST OR PCWIN32 OR ANDROID ) list(APPEND System_Source_Files @@ -252,36 +243,25 @@ set(Shared_Logger_Source_Files set(Shared_Source_Files ../../Source/Shared/xsapi_utils.cpp ../../Source/Shared/xsapi_json_utils.cpp + ../../Source/Shared/fault_injection.h + ../../Source/Shared/fault_injection.cpp ../../Source/Shared/service_call_routed_handler.h ../../Source/Shared/service_call_routed_handler.cpp ../../Source/Shared/errors_legacy.h ../../Source/Shared/errors.cpp ../../Source/Shared/http_call_request_message.cpp ../../Source/Shared/build_version.h - ../../Source/Shared/service_call_logger.cpp - ../../Source/Shared/service_call_logger_data.cpp - ../../Source/Shared/service_call_logging_config.h - ../../Source/Shared/service_call_logging_config.cpp ../../Source/Shared/utils_locales.cpp ../../Source/Shared/web_socket.cpp ../../Source/Shared/xbox_live_app_config_internal.h ../../Source/Shared/xbox_live_app_config.cpp - ../../Source/Shared/xbox_live_services_settings.h - ../../Source/Shared/xbox_live_services_settings.cpp - ../../Source/Shared/xbox_system_factory.cpp ../../Source/Shared/Shared_macros.h ../../Source/Shared/xsapi_utils.h ../../Source/Shared/xsapi_json_utils.h ../../Source/Shared/perf_tester.h - ../../Source/Shared/service_call_logger.h - ../../Source/Shared/service_call_logger_data.h - ../../Source/Shared/service_call_logger_protocol.h ../../Source/Shared/web_socket.h - ../../Source/Shared/xbox_system_factory.h ../../Source/Shared/http_headers.h ../../Source/Shared/http_call_request_message_internal.h - ../../Source/Shared/telemetry.h - ../../Source/Shared/telemetry.cpp ../../Source/Shared/internal_mem.h ../../Source/Shared/internal_mem.cpp ../../Source/Shared/async_helpers.h @@ -301,8 +281,6 @@ set(Shared_Source_Files ../../Source/Shared/http_utils.h ../../Source/Shared/http_utils.cpp ../../Source/Shared/internal_types.h - ../../Source/Shared/http_call_legacy.h - ../../Source/Shared/http_call_legacy.cpp ../../Source/Shared/public_utils_legacy.h ../../Source/Shared/public_utils_legacy.cpp ) @@ -322,13 +300,6 @@ if( UWP ) ) endif() -if ( UWP OR XDK OR UNITTEST ) - list(APPEND - Shared_Source_Files - ../../Source/Shared/service_call_logger_protocol.cpp - ) -endif() - if ( ANDROID ) list(APPEND Shared_Source_Files @@ -349,7 +320,8 @@ if ( ANDROID ) ../../Source/Shared/a/utils_a.cpp ../../Source/Shared/a/xbox_live_app_config_jni.cpp ../../Source/Shared/a/xbox_live_app_config_static_glue.h - ../../Source/Shared/a/telemetry_a.cpp + ../../Source/Shared/http_call_legacy.h + ../../Source/Shared/http_call_legacy.cpp ) endif() @@ -782,7 +754,6 @@ set(UnitTests_Source_Files_Tests ../../Tests/UnitTests/Tests/Shared/HttpCallTests.cpp ../../Tests/UnitTests/Tests/Shared/HttpCallSettingsTests.cpp ../../Tests/UnitTests/Tests/Shared/LogTests.cpp - ../../Tests/UnitTests/Tests/Shared/ServiceCallLoggerTests.cpp ../../Tests/UnitTests/Tests/Shared/XboxLiveContextTests.cpp ../../Tests/UnitTests/Tests/Shared/XboxLiveCallbackTests.cpp ../../Tests/UnitTests/Tests/Shared/GlobalTests.cpp diff --git a/Utilities/VSOBuildScripts/gdkDownloadBuild.ps1 b/Utilities/VSOBuildScripts/gdkDownloadBuild.ps1 new file mode 100644 index 00000000..34af5d58 --- /dev/null +++ b/Utilities/VSOBuildScripts/gdkDownloadBuild.ps1 @@ -0,0 +1,46 @@ +$destPath = $args[0] +$url = $args[1] + +if( $url ) +{ + if ($url -is [uri]) + { + $url = $url.ToString() + } + if ($url.IndexOf('?') -ge 0) + { + $query = ($url -split '\?')[1] + $query = $query.Split('#')[0] + foreach ($q in ($query -split '&')) + { + $kv = $($q + '=') -split '=' + $varName = [uri]::UnescapeDataString($kv[0]).Trim() + $varValue = [uri]::UnescapeDataString($kv[1]) + New-Variable -Name $varname -Value $varValue -Force + } + } + + Write-Host "`$buildId = $buildId" + Write-Host "`$destPath = $destPath" + + # az login if needed + az config set extension.use_dynamic_install=yes_without_prompt + $account = az account show + if( !$account ) + { + [Console]::ResetColor() + az login + } + + az pipelines runs artifact download --run-id $buildId --path $destPath\gdk --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2019_Debug + az pipelines runs artifact download --run-id $buildId --path $destPath\gdk --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2019_Release + az pipelines runs artifact download --run-id $buildId --path $destPath\gdk --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2017_Debug + az pipelines runs artifact download --run-id $buildId --path $destPath\gdk --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2017_Release +} +else +{ + Write-Warning "gdkDownloadBuild.ps1 `"destPath`" `"buildURL`"" + Write-Warning "" + Write-Warning "Example:" + Write-Warning ".\gdkDownloadBuild.ps1 c:\test `"https://microsoft.visualstudio.com/Xbox.Services/_build/results?buildId=30866009&view=logs&j=19f53634-0cc9-5f8f-beda-93fbd1295bdf&t=aa6975a6-c137-5e34-3a5f-3ba934582e17&l=66`"" +} diff --git a/Utilities/VSOBuildScripts/gdkDownloadDocs.ps1 b/Utilities/VSOBuildScripts/gdkDownloadDocs.ps1 new file mode 100644 index 00000000..6b106688 --- /dev/null +++ b/Utilities/VSOBuildScripts/gdkDownloadDocs.ps1 @@ -0,0 +1,43 @@ +$destPath = $args[0] +$url = $args[1] + +if( $url ) +{ + if ($url -is [uri]) + { + $url = $url.ToString() + } + if ($url.IndexOf('?') -ge 0) + { + $query = ($url -split '\?')[1] + $query = $query.Split('#')[0] + foreach ($q in ($query -split '&')) + { + $kv = $($q + '=') -split '=' + $varName = [uri]::UnescapeDataString($kv[0]).Trim() + $varValue = [uri]::UnescapeDataString($kv[1]) + New-Variable -Name $varname -Value $varValue -Force + } + } + + Write-Host "`$buildId = $buildId" + Write-Host "`$destPath = $destPath" + + # az login if needed + az config set extension.use_dynamic_install=yes_without_prompt + $account = az account show + if( !$account ) + { + [Console]::ResetColor() + az login + } + + az pipelines runs artifact download --run-id $buildId --path $destPath\docs --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2019_Docs +} +else +{ + Write-Warning "gdkDownloadDocs.ps1 `"destPath`" `"buildURL`"" + Write-Warning "" + Write-Warning "Example:" + Write-Warning ".\gdkDownloadDocs.ps1 c:\test `"https://microsoft.visualstudio.com/Xbox.Services/_build/results?buildId=30866009&view=logs&j=19f53634-0cc9-5f8f-beda-93fbd1295bdf&t=aa6975a6-c137-5e34-3a5f-3ba934582e17&l=66`"" +} diff --git a/Utilities/VSOBuildScripts/gdkVpackUpdate.ps1 b/Utilities/VSOBuildScripts/gdkVpackUpdate.ps1 new file mode 100644 index 00000000..da9e2855 --- /dev/null +++ b/Utilities/VSOBuildScripts/gdkVpackUpdate.ps1 @@ -0,0 +1,72 @@ +$destOSPath = $args[0] +$url = $args[1] + +if( $url ) +{ + if ($url -is [uri]) + { + $url = $url.ToString() + } + if ($url.IndexOf('?') -ge 0) + { + $query = ($url -split '\?')[1] + $query = $query.Split('#')[0] + foreach ($q in ($query -split '&')) + { + $kv = $($q + '=') -split '=' + $varName = [uri]::UnescapeDataString($kv[0]).Trim() + $varValue = [uri]::UnescapeDataString($kv[1]) + New-Variable -Name $varname -Value $varValue -Force + } + } + + $destPathTemp = Join-Path -Path $destOSPath -ChildPath "\obj\xsapi-vpack-temp" + $destPathXsapi = Join-Path -Path $destOSPath -ChildPath "\src\xbox\devex\vs\extensionSdks\xsapi\c" + Write-Host "" + Write-Host "`$buildId = $buildId" + Write-Host "`$destOSPath = $destOSPath" + Write-Host "`$destPathTemp: $destPathTemp" + Write-Host "`$destPathXsapi: $destPathXsapi" + + Remove-Item -LiteralPath $destPathTemp -Force -Recurse + + # az login if needed + az config set extension.use_dynamic_install=yes_without_prompt + $account = az account show + if( !$account ) + { + [Console]::ResetColor() + az login + } + + az pipelines runs artifact download --run-id $buildId --path $destPathTemp --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2019_VPack_Debug + az pipelines runs artifact download --run-id $buildId --path $destPathTemp --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2019_VPack_Release + az pipelines runs artifact download --run-id $buildId --path $destPathTemp --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2017_VPack_Debug + az pipelines runs artifact download --run-id $buildId --path $destPathTemp --artifact-name XSAPI_Combined_Full_Build_PipelineArtifacts_GDK2017_VPack_Release + + $srcPath17D = Join-Path -Path $destPathTemp -ChildPath "\XSAPI.Debug.Gaming.Desktop.x64.VS2017.man" + $srcPath17R = Join-Path -Path $destPathTemp -ChildPath "\XSAPI.Release.Gaming.Desktop.x64.VS2017.man" + $srcPath19D = Join-Path -Path $destPathTemp -ChildPath "\XSAPI.Debug.Gaming.Desktop.x64.VS2019.man" + $srcPath19R = Join-Path -Path $destPathTemp -ChildPath "\XSAPI.Release.Gaming.Desktop.x64.VS2019.man" + $srcPathInclude = Join-Path -Path $destPathTemp -ChildPath "\include\*" + + $destPath17D = Join-Path -Path $destPathXsapi -ChildPath "\vpackDebug2017\" + $destPath17R = Join-Path -Path $destPathXsapi -ChildPath "\vpackRelease2017\" + $destPath19D = Join-Path -Path $destPathXsapi -ChildPath "\vpackDebug2019\" + $destPath19R = Join-Path -Path $destPathXsapi -ChildPath "\vpackRelease2019\" + $destPathInclude = Join-Path -Path $destPathXsapi -ChildPath "\xdkbuild\include\" + + Copy-Item $srcPath17D -Destination $destPath17D + Copy-Item $srcPath17R -Destination $destPath17R + Copy-Item $srcPath19D -Destination $destPath19D + Copy-Item $srcPath19R -Destination $destPath19R + Copy-Item $srcPathInclude -Destination $destPathInclude -Recurse -Force +} +else +{ + Write-Warning "gdkVpackUpdate.ps1 `"OSPath`" `"buildURL`"" + Write-Warning "" + Write-Warning "Example:" + Write-Warning ".\gdkVpackUpdate.ps1 d:\os `"https://microsoft.visualstudio.com/xsapi/_build/results?buildId=30866009`"" +} + diff --git a/Utilities/VSOBuildScripts/postBuildScript.cmd b/Utilities/VSOBuildScripts/postBuildScript.cmd index dae7e9e7..dfdda244 100644 --- a/Utilities/VSOBuildScripts/postBuildScript.cmd +++ b/Utilities/VSOBuildScripts/postBuildScript.cmd @@ -2,26 +2,32 @@ if "%1" == "local" goto testlocal goto start :testlocal -set TFS_DropLocation=c:\scratch\tfsdrop -mkdir %TFS_DropLocation% -set TFS_VersionNumber=1701.10000 -set TFS_SourcesDirectory=%CD%\..\.. +set BUILD_BINARIESDIRECTORY=%CD%\..\..\Bins +set BUILD_SOURCESDIRECTORY=%CD%\..\.. + goto serializeForPostbuild :start -if "%XES_SERIALPOSTBUILDREADY%" == "True" goto serializeForPostbuild -goto done + +rem if "%XES_SERIALPOSTBUILDREADY%" == "True" goto serializeForPostbuild +rem goto done :serializeForPostbuild echo Running postBuildScript.cmd echo on -if "%BUILD_DEFINITIONNAME%" == "XSAPI_Rolling" goto finalize +set + +set SDK_DROP_LOCATION=%BUILD_BINARIESDIRECTORY%\SDK +rmdir /s /q %SDK_DROP_LOCATION% +mkdir %SDK_DROP_LOCATION% + +if "%BUILD_DEFINITIONNAME%" == "XSAPI_Combined_Rolling_Build" goto finalize setlocal -call %TFS_SourcesDirectory%\Utilities\VSOBuildScripts\setBuildVersion.cmd +call %BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\setBuildVersion.cmd -rem format release numbers +REM ------------------- VERSION SETUP BEGIN ------------------- for /f "tokens=2 delims==" %%G in ('wmic os get localdatetime /value') do set datetime=%%G set DATETIME_YEAR=%datetime:~0,4% set DATETIME_MONTH=%datetime:~4,2% @@ -38,235 +44,233 @@ set NUGET_VERSION_NUMBER=%SDK_RELEASE_YEAR%.%SDK_RELEASE_MONTH%.%SDK_POINT_NAME_ set MINOR_VERSION_NUMBER=%SDK_POINT_NAME_YEAR%%SDK_POINT_NAME_MONTH%%SDK_POINT_NAME_DAY%%SDK_POINT_NAME_VER% if "%NUGET_EXE%" == "" set NUGET_EXE=%AGENT_TOOLSDIRECTORY%\NuGet\4.6.2\x64\nuget.exe -set +REM goto skipCopy -xcopy %TFS_SourcesDirectory%\Utilities\Nuget\* %TFS_DropLocation%\Nuget\ /s /e /q /y -rem goto skipCopy -robocopy /NJS /NJH /MT:16 /S /NP %TFS_SourcesDirectory%\Include %TFS_DropLocation%\Include -robocopy /NJS /NJH /MT:16 /S /NP %TFS_SourcesDirectory%\External\cpprestsdk\Release\include %TFS_DropLocation%\include -robocopy /NJS /NJH /MT:16 /S /NP %TFS_SourcesDirectory%\External\xal\External\libHttpClient\Include %TFS_DropLocation%\include -robocopy /NJS /NJH /MT:16 /S /NP %TFS_SourcesDirectory%\External\xal\Source\Xal\Include %TFS_DropLocation%\include -robocopy /NJS /NJH /MT:16 /S /NP %TFS_SourcesDirectory%\External\xal\Source\XalExtra\Include %TFS_DropLocation%\include -rmdir /s /q %TFS_DropLocation%\include\json_cpp +xcopy %BUILD_SOURCESDIRECTORY%\Utilities\Nuget\* %SDK_DROP_LOCATION%\Nuget\ /s /e /q /y +robocopy /NJS /NJH /MT:16 /S /NP %BUILD_SOURCESDIRECTORY%\Include %SDK_DROP_LOCATION%\Include +robocopy /NJS /NJH /MT:16 /S /NP %BUILD_SOURCESDIRECTORY%\External\xal\External\libHttpClient\Include %SDK_DROP_LOCATION%\include +robocopy /NJS /NJH /MT:16 /S /NP %BUILD_SOURCESDIRECTORY%\External\xal\Source\Xal\Include %SDK_DROP_LOCATION%\include +robocopy /NJS /NJH /MT:16 /S /NP %BUILD_SOURCESDIRECTORY%\External\xal\Source\XalExtra\Include %SDK_DROP_LOCATION%\include +rmdir /s /q %SDK_DROP_LOCATION%\include\json_cpp -rem setup folders for XDK drop -set XDK_BINARIES_DROP=%TFS_DropLocation%\xdkservicesapi -set UWP_BUILD_SHARE=%TFS_DropLocation% -set XDK_BUILD_SHARE=%TFS_DropLocation% +REM ------------------- XDK BEGIN ------------------- +set SDK_DROP_LOCATION_XDK=%SDK_DROP_LOCATION%\XDK +set UWP_BINARIES=%BUILD_BINARIESDIRECTORY% +set XDK_BINARIES=%BUILD_BINARIESDIRECTORY% -set XDK_BIN_BUILD_SHARE_RELEA=%XDK_BUILD_SHARE%\Release\x64 -set XDK_BIN_BUILD_SHARE_DEBUG=%XDK_BUILD_SHARE%\Debug\x64 +set XDK_BIN_BUILD_SHARE_RELEA=%XDK_BINARIES%\Release\x64 +set XDK_BIN_BUILD_SHARE_DEBUG=%XDK_BINARIES%\Debug\x64 -mkdir %XDK_BINARIES_DROP% +mkdir %SDK_DROP_LOCATION_XDK% -rem copy NuGetPackages to build output folder +mkdir %SDK_DROP_LOCATION_XDK% +mkdir %SDK_DROP_LOCATION_XDK%\SourceDist +mkdir %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140 +mkdir %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140 -rem copy includes to build output folder -robocopy /NJS /NJH /MT:16 /S /NP %XDK_BUILD_SHARE%\Include %XDK_BINARIES_DROP%\cpp\include +robocopy /NJS /NJH /MT:16 /S /NP %SDK_DROP_LOCATION%\Include %SDK_DROP_LOCATION_XDK%\cpp\include -rem copy binaries to build output folder -mkdir %XDK_BINARIES_DROP% -mkdir %XDK_BINARIES_DROP%\SourceDist -mkdir %XDK_BINARIES_DROP%\cpp\binaries\release\v140 -mkdir %XDK_BINARIES_DROP%\cpp\binaries\debug\v140 +copy %BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\XDK\Readme.txt %SDK_DROP_LOCATION_XDK%\SourceDist\Readme.txt +%BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\FindAndReplace.exe %SDK_DROP_LOCATION_XDK%\SourceDist\Readme.txt GITCOMMIT %BUILD_SOURCEVERSION% +%BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\FindAndReplace.exe %SDK_DROP_LOCATION_XDK%\SourceDist\Readme.txt VERSION %NUGET_VERSION_NUMBER% -copy %TFS_SourcesDirectory%\Utilities\VSOBuildScripts\XDK\Readme.txt %XDK_BINARIES_DROP%\SourceDist\Readme.txt -%TFS_SourcesDirectory%\Utilities\VSOBuildScripts\FindAndReplace.exe %XDK_BINARIES_DROP%\SourceDist\Readme.txt GITCOMMIT %BUILD_SOURCEVERSION% -%TFS_SourcesDirectory%\Utilities\VSOBuildScripts\FindAndReplace.exe %XDK_BINARIES_DROP%\SourceDist\Readme.txt VERSION %NUGET_VERSION_NUMBER% +echo set MAJOR_VERSION=%SDK_RELEASE_NAME% > %SDK_DROP_LOCATION_XDK%\setver.cmd +echo set MINOR_VERSION=%MINOR_VERSION_NUMBER% >> %SDK_DROP_LOCATION_XDK%\setver.cmd -echo set MAJOR_VERSION=%SDK_RELEASE_NAME% > %XDK_BINARIES_DROP%\setver.cmd -echo set MINOR_VERSION=%MINOR_VERSION_NUMBER% >> %XDK_BINARIES_DROP%\setver.cmd +copy %XDK_BIN_BUILD_SHARE_RELEA%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140\Microsoft.Xbox.Services.140.XDK.Cpp.lib.remove +copy %XDK_BIN_BUILD_SHARE_DEBUG%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140\Microsoft.Xbox.Services.140.XDK.Cpp.lib.remove +copy %XDK_BIN_BUILD_SHARE_RELEA%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140\Microsoft.Xbox.Services.140.XDK.Cpp.pdb +copy %XDK_BIN_BUILD_SHARE_DEBUG%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140\Microsoft.Xbox.Services.140.XDK.Cpp.pdb +copy %XDK_BIN_BUILD_SHARE_RELEA%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140\libHttpClient.140.XDK.C.lib.remove +copy %XDK_BIN_BUILD_SHARE_DEBUG%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140\libHttpClient.140.XDK.C.lib.remove +copy %XDK_BIN_BUILD_SHARE_RELEA%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140 +copy %XDK_BIN_BUILD_SHARE_DEBUG%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140 -copy %XDK_BIN_BUILD_SHARE_RELEA%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.lib %XDK_BINARIES_DROP%\cpp\binaries\release\v140\Microsoft.Xbox.Services.140.XDK.Cpp.lib.remove -copy %XDK_BIN_BUILD_SHARE_DEBUG%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.lib %XDK_BINARIES_DROP%\cpp\binaries\debug\v140\Microsoft.Xbox.Services.140.XDK.Cpp.lib.remove -copy %XDK_BIN_BUILD_SHARE_RELEA%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.pdb %XDK_BINARIES_DROP%\cpp\binaries\release\v140\Microsoft.Xbox.Services.140.XDK.Cpp.pdb -copy %XDK_BIN_BUILD_SHARE_DEBUG%\Microsoft.Xbox.Services.140.XDK.Cpp\Microsoft.Xbox.Services.140.XDK.Cpp.pdb %XDK_BINARIES_DROP%\cpp\binaries\debug\v140\Microsoft.Xbox.Services.140.XDK.Cpp.pdb +copy %XDK_BIN_BUILD_SHARE_RELEA%\casablanca140.Xbox\casablanca140.xbox.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140\casablanca140.xbox.lib.remove +copy %XDK_BIN_BUILD_SHARE_DEBUG%\casablanca140.Xbox\casablanca140.xbox.lib %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140\casablanca140.xbox.lib.remove +copy %XDK_BIN_BUILD_SHARE_RELEA%\casablanca140.Xbox\casablanca140.xbox.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\release\v140\casablanca140.xbox.pdb +copy %XDK_BIN_BUILD_SHARE_DEBUG%\casablanca140.Xbox\casablanca140.xbox.pdb %SDK_DROP_LOCATION_XDK%\cpp\binaries\debug\v140\casablanca140.xbox.pdb -copy %XDK_BIN_BUILD_SHARE_RELEA%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.lib %XDK_BINARIES_DROP%\cpp\binaries\release\v140\libHttpClient.140.XDK.C.lib.remove -copy %XDK_BIN_BUILD_SHARE_DEBUG%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.lib %XDK_BINARIES_DROP%\cpp\binaries\debug\v140\libHttpClient.140.XDK.C.lib.remove -copy %XDK_BIN_BUILD_SHARE_RELEA%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.pdb %XDK_BINARIES_DROP%\cpp\binaries\release\v140 -copy %XDK_BIN_BUILD_SHARE_DEBUG%\libHttpClient.140.XDK.C\libHttpClient.140.XDK.C.pdb %XDK_BINARIES_DROP%\cpp\binaries\debug\v140 - -copy %XDK_BIN_BUILD_SHARE_RELEA%\casablanca140.Xbox\casablanca140.xbox.lib %XDK_BINARIES_DROP%\cpp\binaries\release\v140\casablanca140.xbox.lib.remove -copy %XDK_BIN_BUILD_SHARE_DEBUG%\casablanca140.Xbox\casablanca140.xbox.lib %XDK_BINARIES_DROP%\cpp\binaries\debug\v140\casablanca140.xbox.lib.remove -copy %XDK_BIN_BUILD_SHARE_RELEA%\casablanca140.Xbox\casablanca140.xbox.pdb %XDK_BINARIES_DROP%\cpp\binaries\release\v140\casablanca140.xbox.pdb -copy %XDK_BIN_BUILD_SHARE_DEBUG%\casablanca140.Xbox\casablanca140.xbox.pdb %XDK_BINARIES_DROP%\cpp\binaries\debug\v140\casablanca140.xbox.pdb - -rem laying out the 141 binaries -set PATH_XDK_DROP_BIN=%XDK_BINARIES_DROP%\cpp +set PATH_XDK_DROP_BIN=%SDK_DROP_LOCATION_XDK%\cpp mkdir %PATH_XDK_DROP_BIN%\binaries\release\v141 mkdir %PATH_XDK_DROP_BIN%\binaries\debug\v141 set TYPE=release -copy %TFS_DropLocation%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\Microsoft.Xbox.Services.141.XDK.Cpp.lib.remove -copy %TFS_DropLocation%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\casablanca141.xbox.lib.remove -copy %TFS_DropLocation%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\libHttpClient.141.XDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\Microsoft.Xbox.Services.141.XDK.Cpp.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\casablanca141.xbox.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\libHttpClient.141.XDK.C.lib.remove set TYPE=debug -copy %TFS_DropLocation%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\Microsoft.Xbox.Services.141.XDK.Cpp.lib.remove -copy %TFS_DropLocation%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\casablanca141.xbox.lib.remove -copy %TFS_DropLocation%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\libHttpClient.141.XDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\Microsoft.Xbox.Services.141.XDK.Cpp\Microsoft.Xbox.Services.141.XDK.Cpp.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\Microsoft.Xbox.Services.141.XDK.Cpp.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\casablanca141.Xbox\casablanca141.xbox.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\casablanca141.xbox.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.pdb %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\x64\libHttpClient.141.XDK.C\libHttpClient.141.XDK.C.lib %PATH_XDK_DROP_BIN%\binaries\%TYPE%\v141\libHttpClient.141.XDK.C.lib.remove +REM ------------------- GDK BEGIN ------------------- +set SDK_DROP_LOCATION_GDK=%SDK_DROP_LOCATION%\GDK +set SDK_DROP_LOCATION_GDK_BIN=%SDK_DROP_LOCATION_GDK%\c +mkdir %SDK_DROP_LOCATION_GDK% +mkdir %SDK_DROP_LOCATION_GDK_BIN% +mkdir %SDK_DROP_LOCATION_GDK_BIN%\include +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKXboxExtensionSDKs\release\v141 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKXboxExtensionSDKs\debug\v141 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKXboxExtensionSDKs\release\v142 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKXboxExtensionSDKs\debug\v142 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKDesktopExtensionSDKs\release\v141 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKDesktopExtensionSDKs\debug\v141 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKDesktopExtensionSDKs\release\v142 +mkdir %SDK_DROP_LOCATION_GDK_BIN%\binaries\GSDKDesktopExtensionSDKs\debug\v142 +copy %BUILD_SOURCESDIRECTORY%\Utilities\GDK\Xbox.Services.API.C.props %SDK_DROP_LOCATION_GDK_BIN% -rem setup folders for GDK drop -set PATH_GDK_DROP=%TFS_DropLocation%\gdk-drop -set PATH_GDK_DROP_BIN=%PATH_GDK_DROP%\c -mkdir %PATH_GDK_DROP% -mkdir %PATH_GDK_DROP_BIN% -mkdir %PATH_GDK_DROP_BIN%\include -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKXboxExtensionSDKs\release\v141 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKXboxExtensionSDKs\debug\v141 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKXboxExtensionSDKs\release\v142 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKXboxExtensionSDKs\debug\v142 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKDesktopExtensionSDKs\release\v141 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKDesktopExtensionSDKs\debug\v141 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKDesktopExtensionSDKs\release\v142 -mkdir %PATH_GDK_DROP_BIN%\binaries\GSDKDesktopExtensionSDKs\debug\v142 - -copy %TFS_SourcesDirectory%\Utilities\GDK\Xbox.Services.API.C.props %PATH_GDK_DROP_BIN% - -robocopy /NJS /NJH /MT:16 /S /NP %TFS_DropLocation%\Include %PATH_GDK_DROP_BIN%\include -mkdir %PATH_GDK_DROP_BIN%\include\cpprest -mkdir %PATH_GDK_DROP_BIN%\include\cpprest\details -mkdir %PATH_GDK_DROP_BIN%\include\pplx -copy %TFS_SourcesDirectory%\ThirdPartyNotices.txt %PATH_GDK_DROP_BIN%\include\xsapi-cpp -copy %TFS_SourcesDirectory%\ThirdPartyNotices.txt %PATH_GDK_DROP_BIN%\include\xsapi-c -copy %TFS_SourcesDirectory%\External\xal\External\libHttpClient\ThirdPartyNotices.txt %PATH_GDK_DROP_BIN%\include\httpClient -copy %TFS_SourcesDirectory%\ThirdPartyNotices.txt %PATH_GDK_DROP_BIN%\include\cpprest -copy %TFS_SourcesDirectory%\ThirdPartyNotices.txt %PATH_GDK_DROP_BIN%\include\pplx -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\astreambuf.h %PATH_GDK_DROP_BIN%\include\cpprest\astreambuf.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\asyncrt_utils.h %PATH_GDK_DROP_BIN%\include\cpprest\asyncrt_utils.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\base_uri.h %PATH_GDK_DROP_BIN%\include\cpprest\base_uri.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\containerstream.h %PATH_GDK_DROP_BIN%\include\cpprest\containerstream.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\http_headers.h %PATH_GDK_DROP_BIN%\include\cpprest\http_headers.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\http_msg.h %PATH_GDK_DROP_BIN%\include\cpprest\http_msg.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\json.h %PATH_GDK_DROP_BIN%\include\cpprest\json.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\streams.h %PATH_GDK_DROP_BIN%\include\cpprest\streams.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\uri.h %PATH_GDK_DROP_BIN%\include\cpprest\uri.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\uri_builder.h %PATH_GDK_DROP_BIN%\include\cpprest\uri_builder.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\details\basic_types.h %PATH_GDK_DROP_BIN%\include\cpprest\details\basic_types.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\details\cpprest_compat.h %PATH_GDK_DROP_BIN%\include\cpprest\details\cpprest_compat.h -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\details\http_constants.dat %PATH_GDK_DROP_BIN%\include\cpprest\details\http_constants.dat -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\details\SafeInt3.hpp %PATH_GDK_DROP_BIN%\include\cpprest\details\SafeInt3.hpp -copy %TFS_DropLocation%\include\cpprestinclude\cpprest\details\uri_parser.h %PATH_GDK_DROP_BIN%\include\cpprest\details\uri_parser.h -copy %TFS_DropLocation%\include\cpprestinclude\pplx\pplxtasks.140.h %PATH_GDK_DROP_BIN%\include\pplx\pplxtasks.140.h -copy %TFS_DropLocation%\include\cpprestinclude\pplx\pplxtasks.h %PATH_GDK_DROP_BIN%\include\pplx\pplxtasks.h -rmdir /s /q %PATH_GDK_DROP_BIN%\include\cpprestinclude -rmdir /s /q %PATH_GDK_DROP_BIN%\Include\XalExtra -del %PATH_GDK_DROP_BIN%\include\Xal\xal_android.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_internal_telemetry.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_internal_web_account.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_ios.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_apple.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_generic.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_platform.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_platform_types.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_uwp.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_uwp_user.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_version.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_win32.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_xdk.h -del %PATH_GDK_DROP_BIN%\include\Xal\xal_grts*.h -del %PATH_GDK_DROP_BIN%\include\async.h -del %PATH_GDK_DROP_BIN%\include\asyncProvider.h -del %PATH_GDK_DROP_BIN%\include\asyncQueue.h -del %PATH_GDK_DROP_BIN%\include\asyncQueueEx.h +robocopy /NJS /NJH /MT:16 /S /NP %SDK_DROP_LOCATION%\Include %SDK_DROP_LOCATION_GDK_BIN%\include +mkdir %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest +mkdir %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details +mkdir %SDK_DROP_LOCATION_GDK_BIN%\include\pplx +copy %BUILD_SOURCESDIRECTORY%\ThirdPartyNotices.txt %SDK_DROP_LOCATION_GDK_BIN%\include\xsapi-cpp +copy %BUILD_SOURCESDIRECTORY%\ThirdPartyNotices.txt %SDK_DROP_LOCATION_GDK_BIN%\include\xsapi-c +copy %BUILD_SOURCESDIRECTORY%\External\xal\External\libHttpClient\ThirdPartyNotices.txt %SDK_DROP_LOCATION_GDK_BIN%\include\httpClient +copy %BUILD_SOURCESDIRECTORY%\ThirdPartyNotices.txt %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest +copy %BUILD_SOURCESDIRECTORY%\ThirdPartyNotices.txt %SDK_DROP_LOCATION_GDK_BIN%\include\pplx +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\astreambuf.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\astreambuf.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\asyncrt_utils.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\asyncrt_utils.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\base_uri.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\base_uri.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\containerstream.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\containerstream.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\http_headers.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\http_headers.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\http_msg.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\http_msg.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\json.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\json.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\streams.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\streams.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\uri.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\uri.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\uri_builder.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\uri_builder.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\details\basic_types.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details\basic_types.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\details\cpprest_compat.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details\cpprest_compat.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\details\http_constants.dat %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details\http_constants.dat +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\details\SafeInt3.hpp %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details\SafeInt3.hpp +copy %SDK_DROP_LOCATION%\include\cpprestinclude\cpprest\details\uri_parser.h %SDK_DROP_LOCATION_GDK_BIN%\include\cpprest\details\uri_parser.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\pplx\pplxtasks.140.h %SDK_DROP_LOCATION_GDK_BIN%\include\pplx\pplxtasks.140.h +copy %SDK_DROP_LOCATION%\include\cpprestinclude\pplx\pplxtasks.h %SDK_DROP_LOCATION_GDK_BIN%\include\pplx\pplxtasks.h +rmdir /s /q %SDK_DROP_LOCATION_GDK_BIN%\include\cpprestinclude +rmdir /s /q %SDK_DROP_LOCATION_GDK_BIN%\Include\XalExtra +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_android.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_internal_telemetry.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_internal_web_account.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_ios.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_apple.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_generic.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_platform.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_platform_types.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_uwp.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_uwp_user.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_version.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_win32.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_xdk.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_grts*.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\async.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\asyncProvider.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\asyncQueue.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\asyncQueueEx.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\XAsync.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\XAsyncProvider.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\XTaskQueue.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\grts_base\grts_account_manager.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\grts_base\impersonation_ctx.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\grts_base\nt_user_context.h +del %SDK_DROP_LOCATION_GDK_BIN%\include\Xal\xal_internal_types.h set PLAT=Gaming.Xbox.x64 set PLAT_LAYOUT_NAME=GSDKXboxExtensionSDKs set TYPE=release -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.141.GDK.C.lib.remove set TYPE=debug -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove set PLAT=Gaming.Desktop.x64 set PLAT_LAYOUT_NAME=GSDKDesktopExtensionSDKs set TYPE=release -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove set TYPE=debug -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 -copy %TFS_DropLocation%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %PATH_GDK_DROP_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.141.GDK.C\Microsoft.Xbox.Services.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\Microsoft.Xbox.Services.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\Microsoft.Xbox.Services.142.GDK.C\Microsoft.Xbox.Services.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\Microsoft.Xbox.Services.142.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.141.GDK.C\libHttpClient.141.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v141\libHttpClient.141.GDK.C.lib.remove +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.pdb %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142 +copy %BUILD_BINARIESDIRECTORY%\%TYPE%\%PLAT%\libHttpClient.142.GDK.C\libHttpClient.142.GDK.C.lib %SDK_DROP_LOCATION_GDK_BIN%\binaries\%PLAT_LAYOUT_NAME%\%TYPE%\v142\libHttpClient.142.GDK.C.lib.remove set BUILD_TOOLS=%BUILD_STAGINGDIRECTORY%\sdk.buildtools\buildMachine -copy %BUILD_TOOLS%\GdkCopyHeaders.cmd %PATH_GDK_DROP% -copy %BUILD_TOOLS%\VPackLogReader.exe %PATH_GDK_DROP% -copy %BUILD_TOOLS%\GdkCreateVPack.cmd %PATH_GDK_DROP% -copy %BUILD_TOOLS%\GdkFormatKML.cmd %PATH_GDK_DROP% -copy %BUILD_TOOLS%\GdkCopyOutputToLocal.cmd %PATH_GDK_DROP% -copy %TFS_SourcesDirectory%\Utilities\VSOBuildScripts\setBuildVersion.cmd %PATH_GDK_DROP% -copy %TFS_SourcesDirectory%\Utilities\VSOBuildScripts\ReadSDKVerHeader.exe %PATH_GDK_DROP% -copy %TFS_SourcesDirectory%\Source\Shared\build_version.h %PATH_GDK_DROP% +copy %BUILD_TOOLS%\GdkCopyHeaders.cmd %SDK_DROP_LOCATION_GDK% +copy %BUILD_TOOLS%\VPackLogReader.exe %SDK_DROP_LOCATION_GDK% +copy %BUILD_TOOLS%\GdkCreateVPack.cmd %SDK_DROP_LOCATION_GDK% +copy %BUILD_TOOLS%\GdkFormatKML.cmd %SDK_DROP_LOCATION_GDK% +copy %BUILD_TOOLS%\GdkCopyOutputToLocal.cmd %SDK_DROP_LOCATION_GDK% +copy %BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\setBuildVersion.cmd %SDK_DROP_LOCATION_GDK% +copy %BUILD_SOURCESDIRECTORY%\Utilities\VSOBuildScripts\ReadSDKVerHeader.exe %SDK_DROP_LOCATION_GDK% +copy %BUILD_SOURCESDIRECTORY%\Source\Shared\build_version.h %SDK_DROP_LOCATION_GDK% -set BUILD_INFO_PATH=%PATH_GDK_DROP%\build_info.txt -set BUILD_INFO_BODY="%TFS_DROPLOCATION% https://microsoft.visualstudio.com/Xbox.Services/_build/index?buildId=%BUILD_BUILDID%&_a=summary" +set BUILD_INFO_PATH=%SDK_DROP_LOCATION_GDK%\build_info.txt +set BUILD_INFO_BODY="%SDK_DROP_LOCATION% https://microsoft.visualstudio.com/Xbox.Services/_build/index?buildId=%BUILD_BUILDID%&_a=summary" del %BUILD_INFO_PATH% echo %BUILD_INFO_BODY% > %BUILD_INFO_PATH% -rem setup folders for GDK docs -set PATH_GDK_DOCS=%TFS_DropLocation%\gdk-docs +REM ------------------- GDK DOCS BEGIN------------------- +set PATH_GDK_DOCS=%SDK_DROP_LOCATION%\GDK-Docs set PATH_GDK_DOCS_DROP=%PATH_GDK_DOCS%\docs mkdir %PATH_GDK_DOCS% +rmdir /s /q %PATH_GDK_DOCS% mkdir %PATH_GDK_DOCS_DROP% -call %BUILD_TOOLS%\Noggin\GenerateReferenceDocs.cmd %TFS_DropLocation%\include %PATH_GDK_DOCS_DROP% +call %BUILD_TOOLS%\Noggin\GenerateReferenceDocs.cmd %SDK_DROP_LOCATION%\include %PATH_GDK_DOCS_DROP% copy %BUILD_TOOLS%\Noggin\CopyReferenceDocsToDocsRepo.cmd %PATH_GDK_DOCS% -rem create unity package -REM set UNITY_ASSET_DEST=%TFS_DropLocation%\unity -REM set UNITY_ASSET_SRC=%TFS_SourcesDirectory%\Utilities\IDXboxUnityAssetLayout +REM ------------------- UNITY BEGIN------------------- +REM set SDK_DROP_LOCATION_UNITY=%SDK_DROP_LOCATION%\unity +REM set UNITY_ASSET_SRC=%BUILD_SOURCESDIRECTORY%\Utilities\IDXboxUnityAssetLayout REM set TYPE=x64 -REM copy %UWP_BUILD_SHARE%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% -REM copy %UWP_BUILD_SHARE%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.winmd %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\WinMD +REM copy %UWP_BINARIES%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% +REM copy %UWP_BINARIES%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.winmd %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\WinMD REM set TYPE=ARM -REM copy %UWP_BUILD_SHARE%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% +REM copy %UWP_BINARIES%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% REM set TYPE=x86 -REM copy %UWP_BUILD_SHARE%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% +REM copy %UWP_BINARIES%\Release\%TYPE%\Microsoft.Xbox.Services.141.UWP.WinRT\Microsoft.Xbox.Services.dll %UNITY_ASSET_SRC%\Assets\XboxServicesAPI\Binaries\%TYPE% REM set UNITY_PACKAGE_NAME=%UNITY_ASSET_SRC%\XboxServicesAPI-%SDK_RELEASE_NAME%-%MINOR_VERSION_NUMBER%.unitypackage REM "C:\Program Files\Unity\Editor\Unity.exe" -ea SilentlyContinue -batchmode -logFile "%UNITY_ASSET_SRC%\unity.log" -projectPath "%UNITY_ASSET_SRC%" -exportPackage "Assets\XboxServicesAPI" "%UNITY_PACKAGE_NAME%" -quit -mkdir %UNITY_ASSET_DEST% -robocopy /NJS /NJH /MT:16 /S /NP %UNITY_ASSET_SRC% %UNITY_ASSET_DEST% +rem mkdir %SDK_DROP_LOCATION_UNITY% +rem robocopy /NJS /NJH /MT:16 /S /NP %UNITY_ASSET_SRC% %SDK_DROP_LOCATION_UNITY% if "%1" == "local" goto skipMavenPublish @@ -274,31 +278,30 @@ REM -------------------ANDROID BEGIN------------------- set JAVA_HOME="C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25" if "%ANDROID_HOME%" == "" set ANDROID_HOME=C:\Program Files (x86)\Android\android-sdk rem If we eventually want to include native libs/headers in the maven artifact we can re-enable this -rem call %TFS_SourcesDirectory%\Java\com.microsoft.xboxlive\gradlew.bat --project-dir=%TFS_SourcesDirectory%\Java\com.microsoft.xboxlive copyNdkLibsToAAR -PInputAar=%TFS_BinariesDirectory%\Release\x86\com.microsoft.xboxlive\com.microsoft.xboxlive.aar -POutDir=%TFS_BinariesDirectory%\Release\x86\com.microsoft.xboxlive\ndklibs --info -call %TFS_SourcesDirectory%\Java\com.microsoft.xboxlive\gradlew.bat --project-dir=%TFS_SourcesDirectory%\Java\com.microsoft.xboxlive publish -PInputAar=%TFS_DropLocation%\Release\x86\com.microsoft.xboxlive\com.microsoft.xboxlive.aar --info -call %TFS_SourcesDirectory%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java\gradlew.bat --project-dir=%TFS_SourcesDirectory%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java publish -PInputAar=%TFS_DropLocation%\Release\x86\libHttpClient.141.Android.Java\libHttpClient.aar --info -call %TFS_SourcesDirectory%\external\xal\source\XalAndroidJava\gradlew.bat --project-dir=%TFS_SourcesDirectory%\external\xal\source\XalAndroidJava publish -PaarPath=%TFS_DropLocation%\Release\x86\XalAndroidJava\XalAndroidJava.aar --info +rem call %BUILD_SOURCESDIRECTORY%\Java\com.microsoft.xboxlive\gradlew.bat --project-dir=%BUILD_SOURCESDIRECTORY%\Java\com.microsoft.xboxlive copyNdkLibsToAAR -PInputAar=%TFS_BinariesDirectory%\Release\x86\com.microsoft.xboxlive\com.microsoft.xboxlive.aar -POutDir=%TFS_BinariesDirectory%\Release\x86\com.microsoft.xboxlive\ndklibs --info +call %BUILD_SOURCESDIRECTORY%\Java\com.microsoft.xboxlive\gradlew.bat --project-dir=%BUILD_SOURCESDIRECTORY%\Java\com.microsoft.xboxlive publish -PInputAar=%SDK_DROP_LOCATION%\Release\x86\com.microsoft.xboxlive\com.microsoft.xboxlive.aar --info +call %BUILD_SOURCESDIRECTORY%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java\gradlew.bat --project-dir=%BUILD_SOURCESDIRECTORY%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java publish -PInputAar=%SDK_DROP_LOCATION%\Release\x86\libHttpClient.141.Android.Java\libHttpClient.aar --info +call %BUILD_SOURCESDIRECTORY%\external\xal\source\XalAndroidJava\gradlew.bat --project-dir=%BUILD_SOURCESDIRECTORY%\external\xal\source\XalAndroidJava publish -PaarPath=%SDK_DROP_LOCATION%\Release\x86\XalAndroidJava\XalAndroidJava.aar --info rem Copy Maven output -xcopy %TFS_SourcesDirectory%\Java\com.microsoft.xboxlive\build\Maven\ %TFS_DropLocation%\Maven\ /s /e /q /y -xcopy %TFS_SourcesDirectory%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java\build\Maven\ %TFS_DropLocation%\Maven\ /s /e /q /y -xcopy %TFS_SourcesDirectory%\external\xal\source\XalAndroidJava\build\Maven\ %TFS_DropLocation%\Maven\ /s /e /q /y +xcopy %BUILD_SOURCESDIRECTORY%\Java\com.microsoft.xboxlive\build\Maven\ %SDK_DROP_LOCATION%\Maven\ /s /e /q /y +xcopy %BUILD_SOURCESDIRECTORY%\external\xal\external\libHttpClient\Build\libHttpClient.141.Android.Java\build\Maven\ %SDK_DROP_LOCATION%\Maven\ /s /e /q /y +xcopy %BUILD_SOURCESDIRECTORY%\external\xal\source\XalAndroidJava\build\Maven\ %SDK_DROP_LOCATION%\Maven\ /s /e /q /y rem Copy native android libs and headers -xcopy %TFS_DropLocation%\Include\* %TFS_DropLocation%\Maven\ndk\include\ /s /e /q /y -rmdir /s /q %TFS_DropLocation%\Maven\ndk\include\cpprest -rmdir /s /q %TFS_DropLocation%\Maven\ndk\include\pplx -rmdir /s /q %TFS_DropLocation%\Maven\ndk\include\XalExtra\Win32 -for /R %TFS_DropLocation%\Release\x86\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Release\x86\ -for /R %TFS_DropLocation%\Release\x64\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Release\x64\ -for /R %TFS_DropLocation%\Release\arm\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Release\arm\ -for /R %TFS_DropLocation%\Release\arm64\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Release\arm64\ -for /R %TFS_DropLocation%\Debug\x86\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Debug\x86\ -for /R %TFS_DropLocation%\Debug\x64\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Debug\x64\ -for /R %TFS_DropLocation%\Debug\arm\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Debug\arm\ -for /R %TFS_DropLocation%\Debug\arm64\ %%f in (*.a) do xcopy %%f %TFS_DropLocation%\Maven\ndk\libs\Debug\arm64\ -xcopy %TFS_SourcesDirectory%\Build\xsapi.android.props %TFS_DropLocation%\Maven\ndk\ -REM -------------------ANDROID END------------------- +xcopy %SDK_DROP_LOCATION%\Include\* %SDK_DROP_LOCATION%\Maven\ndk\include\ /s /e /q /y +rmdir /s /q %SDK_DROP_LOCATION%\Maven\ndk\include\cpprest +rmdir /s /q %SDK_DROP_LOCATION%\Maven\ndk\include\pplx +rmdir /s /q %SDK_DROP_LOCATION%\Maven\ndk\include\XalExtra\Win32 +for /R %SDK_DROP_LOCATION%\Release\x86\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Release\x86\ +for /R %SDK_DROP_LOCATION%\Release\x64\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Release\x64\ +for /R %SDK_DROP_LOCATION%\Release\arm\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Release\arm\ +for /R %SDK_DROP_LOCATION%\Release\arm64\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Release\arm64\ +for /R %SDK_DROP_LOCATION%\Debug\x86\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Debug\x86\ +for /R %SDK_DROP_LOCATION%\Debug\x64\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Debug\x64\ +for /R %SDK_DROP_LOCATION%\Debug\arm\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Debug\arm\ +for /R %SDK_DROP_LOCATION%\Debug\arm64\ %%f in (*.a) do xcopy %%f %SDK_DROP_LOCATION%\Maven\ndk\libs\Debug\arm64\ +xcopy %BUILD_SOURCESDIRECTORY%\Build\xsapi.android.props %SDK_DROP_LOCATION%\Maven\ndk\ :skipMavenPublish @echo on @@ -307,33 +310,36 @@ if "%skipNuget%" == "1" goto skipNuget if "%1" == "local" goto skipNuget rem :skipCopy +REM Skipping nuget packages creation until needed +goto skipNuget + +REM -------------------NUGET PACKAGE BEGIN------------------- rem create Cpp.Win32 nuget package -rmdir /s /q %TFS_DropLocation%\include\winrt -rmdir /s /q %TFS_DropLocation%\include\cppwinrt -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.v141.x64.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.v141.x86.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% +rmdir /s /q %SDK_DROP_LOCATION%\include\winrt +rmdir /s /q %SDK_DROP_LOCATION%\include\cppwinrt +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.v141.x64.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.Win32.v141.x86.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% rem create Cpp.UWP nuget package -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.ARM.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.x64.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.x86.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% - +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.ARM.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.x64.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v140.x86.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.ARM.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x64.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.UWP.v141.x86.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% rmdir /s /q %WINSDK_OUTPUT_DEST% rem create Cpp.XDK nuget package -%NUGET_EXE% pack %TFS_DropLocation%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.XboxOneXDK.nuspec -BasePath %TFS_DropLocation% -OutputDirectory %TFS_DropLocation% -Verbosity normal -version %NUGET_VERSION_NUMBER% +%NUGET_EXE% pack %SDK_DROP_LOCATION%\Nuget\Microsoft.Xbox.Live.SDK.Cpp.XboxOneXDK.nuspec -BasePath %SDK_DROP_LOCATION% -OutputDirectory %SDK_DROP_LOCATION% -Verbosity normal -version %NUGET_VERSION_NUMBER% - -mkdir %TFS_DropLocation%\NuGetBinaries\%BUILDCONFIGURATION%\%BUILDPLATFORM% -move %TFS_DropLocation%\*.nupkg %TFS_DropLocation%\NuGetBinaries\%BUILDCONFIGURATION%\%BUILDPLATFORM% +mkdir %SDK_DROP_LOCATION%\NuGetBinaries\%BUILDCONFIGURATION%\%BUILDPLATFORM% +move %SDK_DROP_LOCATION%\*.nupkg %SDK_DROP_LOCATION%\NuGetBinaries\%BUILDCONFIGURATION%\%BUILDPLATFORM% :skipNuget +REM -------------------DONE------------------- :finalize echo. @@ -343,15 +349,3 @@ endlocal :done exit /b - -:GetTarget -@echo off & setlocal -set gt=%temp%\_.vbs -echo set WshShell = WScript.CreateObject("WScript.Shell")>%gt% -echo set Lnk = WshShell.CreateShortcut(WScript.Arguments.Unnamed(0))>>%gt% -echo wscript.Echo Lnk.TargetPath>>%gt% -set script=cscript //nologo %gt% -For /f "delims=" %%a in ( '%script% "%~1"' ) do set target=%%a -del %gt% -endlocal & set %~2=%target% -exit /b \ No newline at end of file diff --git a/Utilities/VSOBuildScripts/postBuildScriptVPack.cmd b/Utilities/VSOBuildScripts/postBuildScriptVPack.cmd new file mode 100644 index 00000000..0ebcd8f3 --- /dev/null +++ b/Utilities/VSOBuildScripts/postBuildScriptVPack.cmd @@ -0,0 +1,44 @@ +if "%1" == "local" goto testlocal +goto start + +:testlocal +set BUILD_BINARIESDIRECTORY=%CD%\..\..\Bins +set BUILD_SOURCESDIRECTORY=%CD%\..\.. + +goto serializeForPostbuild + +:start + +rem if "%XES_SERIALPOSTBUILDREADY%" == "True" goto serializeForPostbuild +rem goto done +:serializeForPostbuild + +echo Running postBuildScriptVPack.cmd +echo on + +set + +set SDK_DROP_LOCATION=%BUILD_BINARIESDIRECTORY%\SDK +mkdir %SDK_DROP_LOCATION% + +if "%BUILD_DEFINITIONNAME%" == "XSAPI_Combined_Rolling_Build" goto finalize + +REM ------------------- GDK BEGIN ------------------- +set SDK_DROP_LOCATION_GDK=%SDK_DROP_LOCATION%\GDK +set SDK_DROP_LOCATION_GDK_VPACK=%SDK_DROP_LOCATION%\GDK-VPack +mkdir %SDK_DROP_LOCATION_GDK_VPACK% +mkdir %SDK_DROP_LOCATION_GDK_VPACK%\include + +robocopy /NJS /NJH /MT:16 /S /NP %SDK_DROP_LOCATION_GDK%\c\include %SDK_DROP_LOCATION_GDK_VPACK%\include +copy %XES_VPACKMANIFESTDIRECTORY%\%XES_VPACKMANIFESTNAME% %SDK_DROP_LOCATION_GDK_VPACK% + +REM -------------------DONE------------------- +:finalize + +echo. +echo Done postBuildScriptVPack.cmd +echo. +endlocal + +:done +exit /b diff --git a/nuget.config b/nuget.config deleted file mode 100644 index f3ccb9c4..00000000 --- a/nuget.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file