This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+206
View File
@@ -0,0 +1,206 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "BufferUtils.h"
#include "StringUtils.h"
#include "ErrorUtils.h"
#if TV_API
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
namespace Microsoft {
namespace Xbox {
namespace GameChat {
Windows::Storage::Streams::IBuffer^
BufferUtils::FastBufferCreate(
_In_ uint32 capacity,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
)
{
// All of this can be done with this C++/CX line:
// Windows::Storage::Streams::IBuffer^ cxBuffer = ref new Buffer(capacity);
//
// However there is a performance hit since inside this call is slow to lookup the activation factory by string.
// The caller should cache the result of GetActivationFactory and reuse it upon sequential calls.
//
// Create the factory like so:
// hr = GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_Streams_Buffer ).Get(), &bufferFactory);
CHAT_THROW_INVALIDARGUMENT_IF_NULL( bufferFactory );
HRESULT hr;
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> abiBuffer;
hr = bufferFactory->Create( capacity, &abiBuffer );
CHAT_THROW_IF_HR_FAILED( hr );
CHAT_THROW_E_POINTER_IF_NULL( abiBuffer );
Windows::Storage::Streams::IBuffer^ cxBuffer = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(abiBuffer.Get());
return cxBuffer;
}
Windows::Storage::Streams::IBuffer^
BufferUtils::BufferCopy(
_In_ Windows::Storage::Streams::IBuffer^ source,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
)
{
CHAT_THROW_INVALIDARGUMENT_IF_NULL(source);
byte* srcBufferBytes = nullptr;
GetBufferBytes( source, &srcBufferBytes );
Windows::Storage::Streams::IBuffer^ destination = BufferUtils::FastBufferCreate(source->Length, bufferFactory);
byte* destBufferBytes = nullptr;
GetBufferBytes( destination, &destBufferBytes );
errno_t err = memcpy_s(
destBufferBytes,
destination->Capacity,
srcBufferBytes,
source->Length
);
// Params were validated prior to the memcpy_s call, so this should never happen
CHAT_THROW_HR_IF(err != 0, E_FAIL);
destination->Length = source->Length;
return destination;
}
void BufferUtils::GetBufferBytes(
_In_ Windows::Storage::Streams::IBuffer^ buffer,
_Outptr_ byte** ppOut
)
{
if ( ppOut == nullptr || buffer == nullptr )
{
throw ref new Platform::InvalidArgumentException();
}
*ppOut = nullptr;
Microsoft::WRL::ComPtr<IInspectable> srcBufferInspectable(reinterpret_cast<IInspectable*>( buffer ));
Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> srcBufferByteAccess;
HRESULT hr = srcBufferInspectable.As(&srcBufferByteAccess);
CHAT_THROW_IF_HR_FAILED(hr);
hr = srcBufferByteAccess->Buffer(ppOut);
CHAT_THROW_IF_HR_FAILED(hr);
}
Windows::Storage::Streams::IBuffer^ BufferUtils::CreateBufferFromBytes(
_In_reads_bytes_(sourceByteBufferSize) byte* sourceByteBuffer,
_In_ UINT sourceByteBufferSize,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
)
{
Windows::Storage::Streams::IBuffer^ destBuffer = BufferUtils::FastBufferCreate(sourceByteBufferSize, bufferFactory);
byte* destBufferBytes = nullptr;
GetBufferBytes( destBuffer, &destBufferBytes );
errno_t err = memcpy_s( destBufferBytes, destBuffer->Capacity, sourceByteBuffer, sourceByteBufferSize );
CHAT_THROW_HR_IF(err != 0, E_FAIL);
destBuffer->Length = sourceByteBufferSize;
return destBuffer;
}
Platform::String^
BufferUtils::GetBase64String(
_In_ Windows::Storage::Streams::IBuffer^ buffer
)
{
if( buffer == nullptr )
{
return L"";
}
UINT32 length = buffer->Length;
if ( !length )
{
return L"";
}
// Read off the buffer, encode in base64, and push onto the string.
auto dataReader = Windows::Storage::Streams::DataReader::FromBuffer( buffer );
Platform::String^ base64EncodedConnectivityInfo = ref new Platform::String(L"");
static const char s_chBase64EncodingTable[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
while (length >= 3)
{
UINT8 byte0 = dataReader->ReadByte();
UINT8 byte1 = dataReader->ReadByte();
UINT8 byte2 = dataReader->ReadByte();
wchar_t Digit[5];
UCHAR index0 = (byte0 >> 2);
UCHAR index1 = ((byte0 & 3/*00000011*/) << 4) + ((byte1 & 240/*11110000*/) >> 4);
UCHAR index2 = ((byte2 & 192/*11000000*/) >> 6) + ((byte1 & 15/*00001111*/) << 2);
UCHAR index3 = (byte2 & 63/*00111111*/ );
Digit[0] = s_chBase64EncodingTable[index0];
Digit[1] = s_chBase64EncodingTable[index1];
Digit[2] = s_chBase64EncodingTable[index2];
Digit[3] = s_chBase64EncodingTable[index3];
Digit[4] = 0;
base64EncodedConnectivityInfo += ref new Platform::String(Digit);
length -= 3;
}
if(length == 1) // 2 equals
{
UINT8 byte0 = dataReader->ReadByte();
UINT8 byte1 = 0;
wchar_t Digit[5];
UCHAR index0 = (byte0 >> 2);
UCHAR index1 = ((byte0 & 3/*00000011*/) << 4) + ((byte1 & 240/*11110000*/) >> 4);
Digit[0] = s_chBase64EncodingTable[index0];
Digit[1] = s_chBase64EncodingTable[index1];
Digit[2] = L'=';
Digit[3] = L'=';
Digit[4] = 0;
base64EncodedConnectivityInfo += ref new Platform::String(Digit);
}
else if(length == 2) // 1 equals
{
UINT8 byte0 = dataReader->ReadByte();
UINT8 byte1 = dataReader->ReadByte();
UINT8 byte2 = 0;
wchar_t Digit[5];
UCHAR index0 = (byte0 >> 2);
UCHAR index1 = ((byte0 & 3/*00000011*/) << 4) + ((byte1 & 240/*11110000*/) >> 4);
UCHAR index2 = ((byte2 & 192/*11000000*/) >> 6) + ((byte1 & 15/*00001111*/) << 2);
Digit[0] = s_chBase64EncodingTable[index0];
Digit[1] = s_chBase64EncodingTable[index1];
Digit[2] = s_chBase64EncodingTable[index2];
Digit[3] = L'=';
Digit[4] = 0;
base64EncodedConnectivityInfo += ref new Platform::String(Digit);
}
return base64EncodedConnectivityInfo;
}
int
BufferUtils::GetLength(
_In_ Windows::Storage::Streams::IBuffer^ buffer
)
{
return ( buffer != nullptr ) ? buffer->Length : 0;
}
}}}
#endif
+66
View File
@@ -0,0 +1,66 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
private class BufferUtils
{
public:
static Windows::Storage::Streams::IBuffer^ FastBufferCreate(
_In_ uint32 capacity,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
);
/// <summary>
/// Creates a copy of a buffer from an existing buffer
/// </summary>
/// <param name="source">The buffer to copy</param>
/// <returns>A new buffer that contains the contents of the input buffer</returns>
static Windows::Storage::Streams::IBuffer^ BufferCopy(
_In_ Windows::Storage::Streams::IBuffer^ source,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
);
/// <summary>
/// Gets a byte* from a buffer
/// </summary>
/// <param name="buffer">The buffer to get the byte* from</param>
/// <param name="ppOut">A pointer to a byte* that will be set</param>
static void GetBufferBytes(
_In_ Windows::Storage::Streams::IBuffer^ buffer,
_Outptr_ byte** ppOut
);
/// <summary>
/// Creates a new buffer from a byte array
/// </summary>
/// <param name="sourceByteBuffer">The input byte array</param>
/// <param name="sourceByteBufferSize">The length of the sourceByteBuffer in number of bytes</param>
/// <returns>A new buffer that contains the contents of byte array</returns>
static Windows::Storage::Streams::IBuffer^ CreateBufferFromBytes(
_In_reads_bytes_(sourceByteBufferSize) byte* sourceByteBuffer,
_In_ UINT sourceByteBufferSize,
_In_ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory
);
static Platform::String^ GetBase64String(
_In_ Windows::Storage::Streams::IBuffer^ buffer
);
static int GetLength(
_In_ Windows::Storage::Streams::IBuffer^ buffer
);
};
}}}
#endif
+53
View File
@@ -0,0 +1,53 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#define TEXTW(quote) _TEXTW(quote)
#define _TEXTW(quote) L##quote
#define CHAT_LOG_EXCEPTION(hr) Microsoft::Xbox::GameChat::StringUtils::GetLogExceptionDebugInfo(hr, TEXTW(__FUNCTION__), TEXTW(__FILE__), __LINE__ );
#define CHAT_LOG_INFO_MSG(msg) { if (m_chatManagerSettings->IsAtDiagnosticsTraceLevel(GameChatDiagnosticsTraceLevel::Info)) { LogComment( msg ); } }
#define CHAT_LOG_ERROR_MSG(msg) { if (m_chatManagerSettings->IsAtDiagnosticsTraceLevel(GameChatDiagnosticsTraceLevel::Error)) { LogComment( msg ); } }
#define CHAT_LOG_VERBOSE_MSG(msg) { if (m_chatManagerSettings->IsAtDiagnosticsTraceLevel(GameChatDiagnosticsTraceLevel::Verbose)) { LogComment( msg ); } }
#define CHAT_THROW_INVALIDARGUMENT_IF(x) if ( x ) { CHAT_LOG_EXCEPTION(E_INVALIDARG); throw ref new Platform::InvalidArgumentException(); }
#define CHAT_THROW_INVALIDARGUMENT_IF_NULL(x) if ( ( x ) == nullptr ) { CHAT_LOG_EXCEPTION(E_INVALIDARG); throw ref new Platform::InvalidArgumentException(); }
#define CHAT_THROW_E_POINTER_IF_NULL(x) if ( ( x ) == nullptr ) { CHAT_LOG_EXCEPTION(E_POINTER); throw ref new Platform::COMException(E_POINTER); }
#define CHAT_THROW_E_POINTER_IF_NULL_WITH_LOG(x,msg) if ( ( x ) == nullptr ) { CHAT_LOG_ERROR_MSG( msg ); CHAT_LOG_EXCEPTION(E_POINTER); throw ref new Platform::COMException(E_POINTER); }
#define CHAT_THROW_INVALIDARGUMENT_IF_STRING_EMPTY(x) { auto y = x; if ( y->IsEmpty() ) { CHAT_LOG_EXCEPTION(E_INVALIDARG); throw ref new Platform::InvalidArgumentException(); } }
#define CHAT_THROW_IF_HR_FAILED(hr) { HRESULT hr2 = hr; if ( FAILED( hr2 ) ) { CHAT_LOG_EXCEPTION(hr2); throw ref new Platform::COMException(hr2); } }
#define CHAT_THROW_HR(hr) { CHAT_LOG_EXCEPTION(hr); throw ref new Platform::COMException(hr); }
#define CHAT_THROW_HR_IF(x,hr) if ( x ) { CHAT_LOG_EXCEPTION(hr); throw ref new Platform::COMException(hr); }
#define CHAT_THROW_WIN32_IF(x,e) if ( x ) { HRESULT hr = __HRESULT_FROM_WIN32(e); CHAT_LOG_EXCEPTION(hr); throw ref new Platform::COMException(hr); }
#ifndef E_INVALIDARG_IF
#define E_INVALIDARG_IF(x) if ( x ) { return E_INVALIDARG; }
#endif
#ifndef E_POINTER_IF_NULL
#define E_POINTER_IF_NULL(x) if ( ( x ) == nullptr ) { return E_POINTER; }
#endif
#ifndef E_POINTER_OR_INVALIDARG_IF_STRING_EMPTY
#define E_POINTER_OR_INVALIDARG_IF_STRING_EMPTY(x) { auto y = x; E_POINTER_IF_NULL( y ); E_INVALIDARG_IF( wcslen( y ) == 0 ); }
#endif
#ifndef CHECKHR_EXIT
#define CHECKHR_EXIT(hrResult) { hr = hrResult; if ( FAILED( hr ) ) { goto exit; } }
#endif
#define TV_API (WINAPI_FAMILY == WINAPI_FAMILY_TV_APP | WINAPI_FAMILY == WINAPI_FAMILY_TV_TITLE)
#ifdef PRERELEASE
#define PUBLIC_ONLY_IN_PRERELEASE public
#define PUBLIC_ONLY_IN_PRERELEASE_INTERNAL_OTHERWISE public
#else
#define PUBLIC_ONLY_IN_PRERELEASE private
#define PUBLIC_ONLY_IN_PRERELEASE_INTERNAL_OTHERWISE internal
#endif
#ifdef INTERNAL_BUILD
#define PUBLIC_ONLY_IN_DEVKIT private
#else
#define PUBLIC_ONLY_IN_DEVKIT public
#endif
+112
View File
@@ -0,0 +1,112 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "Clock.h"
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
Clock::Clock() :
m_heartbeats(0)
{
m_timerFrequency.QuadPart = 0;
m_timerStart.QuadPart = 0;
m_countPerPeriod.QuadPart = 0;
}
void Clock::Initialize( UINT uPeriodMS )
{
if (!QueryPerformanceFrequency(&m_timerFrequency))
{
assert(false);
}
SetInterval(uPeriodMS);
}
void Clock::SetInterval( UINT uPeriodMS )
{
m_countPerPeriod.QuadPart = ( m_timerFrequency.QuadPart * uPeriodMS ) / c_uOneSecondInMS;
}
void Clock::SleepUntilNextHeartbeat()
{
LARGE_INTEGER timeOfNextHeartbeat = GetNextHeartbeat();
LARGE_INTEGER timeNow;
m_heartbeats++; // so that the next one will be 20ms (or whatever) later...
if (!QueryPerformanceCounter(&timeNow))
{
assert(false);
}
LONGLONG timeDelta = timeOfNextHeartbeat.QuadPart - timeNow.QuadPart;
if ( timeDelta > 0 )
{
LONGLONG numberOfMilliSecondsSinceLast = c_uOneSecondInMS * timeDelta / m_timerFrequency.QuadPart;
WCHAR text[200] = {0};
swprintf_s( text, L"I Slept: %I64d", numberOfMilliSecondsSinceLast );
OutputDebugString( text );
DWORD dwSleepTime = static_cast<DWORD>(numberOfMilliSecondsSinceLast);
Sleep( dwSleepTime );
}
}
DWORD Clock::WaitForEventsOrHeartbeat( HANDLE hObject, HANDLE hObject2 )
{
LARGE_INTEGER liExpected = GetNextHeartbeat();
LARGE_INTEGER liNow;
m_heartbeats++; // so that the next one will be 20ms (or whatever) later...
if (!QueryPerformanceCounter(&liNow))
{
assert(false);
}
LONGLONG llDiff = liExpected.QuadPart - liNow.QuadPart;
HANDLE aObjects[2];
aObjects[0] = hObject;
aObjects[1] = hObject2;
if ( llDiff > 0 )
{
DWORD dwSleepTime = static_cast<DWORD>(c_uOneSecondInMS * llDiff / m_timerFrequency.QuadPart);
return ::WaitForMultipleObjectsEx( 2, aObjects, false, dwSleepTime, false );
}
// we're already late, no need to wait, but we still need to test the object
return ::WaitForMultipleObjectsEx( 2, aObjects, false, 0, false );
}
LARGE_INTEGER Clock::GetNextHeartbeat()
{
LARGE_INTEGER timeExpected;
// Update Start
if ( m_timerStart.QuadPart == 0 )
{
if (!QueryPerformanceCounter( &m_timerStart ))
{
assert(false);
}
m_heartbeats = 1; // we are on the very first heartbeat
}
timeExpected.QuadPart = m_timerStart.QuadPart + (m_countPerPeriod.QuadPart * m_heartbeats);
return timeExpected;
}
}}}
#endif
+40
View File
@@ -0,0 +1,40 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
class Clock
{
public:
Clock();
void Initialize( UINT uPeriodMS );
void SetInterval( UINT uPeriodMS );
void SleepUntilNextHeartbeat();
DWORD WaitForEventsOrHeartbeat(HANDLE hObject, HANDLE hObject2);
private:
static const UINT c_uOneSecondInMS = 1000;
UINT m_heartbeats;
LARGE_INTEGER m_timerFrequency;
LARGE_INTEGER m_timerStart;
LARGE_INTEGER m_countPerPeriod;
LARGE_INTEGER GetNextHeartbeat();
};
}}}
#endif
+546
View File
@@ -0,0 +1,546 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "ErrorUtils.h"
#if TV_API
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
namespace Microsoft {
namespace Xbox {
namespace GameChat {
enum WebErrorStatus
{
WebErrorStatus_Unknown = 0,
WebErrorStatus_CertificateCommonNameIsIncorrect = 1,
WebErrorStatus_CertificateExpired = 2,
WebErrorStatus_CertificateContainsErrors = 3,
WebErrorStatus_CertificateRevoked = 4,
WebErrorStatus_CertificateIsInvalid = 5,
WebErrorStatus_ServerUnreachable = 6,
WebErrorStatus_Timeout = 7,
WebErrorStatus_ErrorHttpInvalidServerResponse = 8,
WebErrorStatus_ConnectionAborted = 9,
WebErrorStatus_ConnectionReset = 10,
WebErrorStatus_Disconnected = 11,
WebErrorStatus_HttpToHttpsOnRedirection = 12,
WebErrorStatus_HttpsToHttpOnRedirection = 13,
WebErrorStatus_CannotConnect = 14,
WebErrorStatus_HostNameNotResolved = 15,
WebErrorStatus_OperationCanceled = 16,
WebErrorStatus_RedirectFailed = 17,
WebErrorStatus_UnexpectedStatusCode = 18,
WebErrorStatus_UnexpectedRedirection = 19,
WebErrorStatus_UnexpectedClientError = 20,
WebErrorStatus_UnexpectedServerError = 21,
WebErrorStatus_MultipleChoices = 300,
WebErrorStatus_MovedPermanently = 301,
WebErrorStatus_Found = 302,
WebErrorStatus_SeeOther = 303,
WebErrorStatus_NotModified = 304,
WebErrorStatus_UseProxy = 305,
WebErrorStatus_TemporaryRedirect = 307,
WebErrorStatus_BadRequest = 400,
WebErrorStatus_Unauthorized = 401,
WebErrorStatus_PaymentRequired = 402,
WebErrorStatus_Forbidden = 403,
WebErrorStatus_NotFound = 404,
WebErrorStatus_MethodNotAllowed = 405,
WebErrorStatus_NotAcceptable = 406,
WebErrorStatus_ProxyAuthenticationRequired = 407,
WebErrorStatus_RequestTimeout = 408,
WebErrorStatus_Conflict = 409,
WebErrorStatus_Gone = 410,
WebErrorStatus_LengthRequired = 411,
WebErrorStatus_PreconditionFailed = 412,
WebErrorStatus_RequestEntityTooLarge = 413,
WebErrorStatus_RequestUriTooLong = 414,
WebErrorStatus_UnsupportedMediaType = 415,
WebErrorStatus_RequestedRangeNotSatisfiable = 416,
WebErrorStatus_ExpectationFailed = 417,
WebErrorStatus_InternalServerError = 500,
WebErrorStatus_NotImplemented = 501,
WebErrorStatus_BadGateway = 502,
WebErrorStatus_ServiceUnavailable = 503,
WebErrorStatus_GatewayTimeout = 504,
WebErrorStatus_HttpVersionNotSupported = 505
};
HRESULT
ErrorUtils::ConvertHttpStatusCodeToHR(
_In_ uint32 httpStatusCode
)
{
HRESULT hr = HTTP_E_STATUS_UNEXPECTED;
// 2xx are http success codes
if ((httpStatusCode >= 200) && (httpStatusCode < 300))
{
hr = S_OK;
}
// MSXML XHR bug: get_status() returns HTTP/1223 for HTTP/204:
// http://blogs.msdn.com/b/ieinternals/archive/2009/07/23/the-ie8-native-xmlhttprequest-object.aspx
// treat it as success code as well
else if ( httpStatusCode == 1223 )
{
hr = S_OK;
}
else
{
switch(httpStatusCode)
{
//
// 101 server has switched protocols in upgrade header. Not suppose to happen in product.
//
case 101:
hr = INET_E_UNKNOWN_PROTOCOL;
break;
//
// 300 Multiple Choices
//
case WebErrorStatus::WebErrorStatus_MultipleChoices:
hr = HTTP_E_STATUS_AMBIGUOUS;
break;
//
// 301 Moved Permanently
//
case WebErrorStatus::WebErrorStatus_MovedPermanently:
hr = HTTP_E_STATUS_MOVED;
break;
//
// 302 Found
//
case WebErrorStatus::WebErrorStatus_Found:
hr = HTTP_E_STATUS_REDIRECT;
break;
//
// 303 See Other
//
case WebErrorStatus::WebErrorStatus_SeeOther:
hr = HTTP_E_STATUS_REDIRECT_METHOD;
break;
//
// 304 Not Modified
//
case WebErrorStatus::WebErrorStatus_NotModified:
hr = HTTP_E_STATUS_NOT_MODIFIED;
break;
//
// 305 Use Proxy
//
case WebErrorStatus::WebErrorStatus_UseProxy:
hr = HTTP_E_STATUS_USE_PROXY;
break;
//
// 307 Temporary Redirect
//
case WebErrorStatus::WebErrorStatus_TemporaryRedirect:
hr = HTTP_E_STATUS_REDIRECT_KEEP_VERB;
break;
//
// 400 Bad Request
//
case WebErrorStatus::WebErrorStatus_BadRequest:
hr = HTTP_E_STATUS_BAD_REQUEST;
break;
//
// 401 Unauthorized
//
case WebErrorStatus::WebErrorStatus_Unauthorized:
hr = HTTP_E_STATUS_DENIED;
break;
//
// 402 Payment Required
//
case WebErrorStatus::WebErrorStatus_PaymentRequired:
hr = HTTP_E_STATUS_PAYMENT_REQ;
break;
//
// 403 Forbidden.
//
case WebErrorStatus::WebErrorStatus_Forbidden:
hr = HTTP_E_STATUS_FORBIDDEN;
break;
//
// 404 Not Found.
//
case WebErrorStatus::WebErrorStatus_NotFound:
hr = HTTP_E_STATUS_NOT_FOUND;
break;
//
// 405 Method Not Allowed
//
case WebErrorStatus::WebErrorStatus_MethodNotAllowed:
hr = HTTP_E_STATUS_BAD_METHOD;
break;
//
// 406 Not Acceptable
//
case WebErrorStatus::WebErrorStatus_NotAcceptable:
hr = HTTP_E_STATUS_NONE_ACCEPTABLE;
break;
//
// 407 Proxy Authentication Required
//
case WebErrorStatus::WebErrorStatus_ProxyAuthenticationRequired:
hr = HTTP_E_STATUS_PROXY_AUTH_REQ;
break;
//
// 408 Request Timeout
//
case WebErrorStatus::WebErrorStatus_RequestTimeout:
hr = HTTP_E_STATUS_REQUEST_TIMEOUT;
break;
//
// 409 Conflict
//
case WebErrorStatus::WebErrorStatus_Conflict:
hr = HTTP_E_STATUS_CONFLICT;
break;
//
// 410 Gone
//
case WebErrorStatus::WebErrorStatus_Gone:
hr = HTTP_E_STATUS_GONE;
break;
//
// 411 Length Required
//
case WebErrorStatus::WebErrorStatus_LengthRequired:
hr = HTTP_E_STATUS_LENGTH_REQUIRED;
break;
//
// 412 Precondition Failed
//
case WebErrorStatus::WebErrorStatus_PreconditionFailed:
hr = HTTP_E_STATUS_PRECOND_FAILED;
break;
//
// 413 Request Entity Too Large
//
case WebErrorStatus::WebErrorStatus_RequestEntityTooLarge:
hr = HTTP_E_STATUS_REQUEST_TOO_LARGE;
break;
//
// 414 Request URI Too Long
//
case WebErrorStatus::WebErrorStatus_RequestUriTooLong:
hr = HTTP_E_STATUS_URI_TOO_LONG;
break;
//
// 415 Unsupported Media Type
//
case WebErrorStatus::WebErrorStatus_UnsupportedMediaType:
hr = HTTP_E_STATUS_UNSUPPORTED_MEDIA;
break;
//
// 416 Requested Range Not Satisfiable
//
case WebErrorStatus::WebErrorStatus_RequestedRangeNotSatisfiable:
hr = HTTP_E_STATUS_RANGE_NOT_SATISFIABLE;
break;
//
// 417 Expectation Failed
//
case WebErrorStatus::WebErrorStatus_ExpectationFailed:
hr = HTTP_E_STATUS_EXPECTATION_FAILED;
break;
//
// 449 Retry after doing the appropriate action.
//
case 449:
hr = HTTP_E_STATUS_BAD_REQUEST;
break;
//
// 500 Internal Server Error
//
case WebErrorStatus::WebErrorStatus_InternalServerError:
hr = HTTP_E_STATUS_SERVER_ERROR;
break;
//
// 501 Not Implemented
//
case WebErrorStatus::WebErrorStatus_NotImplemented:
hr = HTTP_E_STATUS_NOT_SUPPORTED;
break;
//
// 502 Bad Gateway
//
case WebErrorStatus::WebErrorStatus_BadGateway:
hr = HTTP_E_STATUS_BAD_GATEWAY;
break;
//
// 503 Service Unavailable
//
case WebErrorStatus::WebErrorStatus_ServiceUnavailable:
hr = HTTP_E_STATUS_SERVICE_UNAVAIL;
break;
//
// 504 Gateway Timeout
//
case WebErrorStatus::WebErrorStatus_GatewayTimeout:
hr = HTTP_E_STATUS_GATEWAY_TIMEOUT;
break;
//
// 505 HTTP Version Not Supported.
//
case WebErrorStatus::WebErrorStatus_HttpVersionNotSupported:
hr = HTTP_E_STATUS_VERSION_NOT_SUP;
break;
default:
hr = HTTP_E_STATUS_UNEXPECTED;
break;
}
}
return hr;
}
HRESULT
ErrorUtils::ConvertExceptionToHRESULT()
{
// Default value, if there is no exception appears, return S_OK
HRESULT hr = S_OK;
try
{
throw;
}
// std exceptions
catch( const std::bad_alloc& ) // is an exception
{
hr = E_OUTOFMEMORY;
}
catch( const std::invalid_argument& ) // is a logic_error
{
hr = E_INVALIDARG;
}
catch( const std::domain_error& ) // is a logic_error
{
hr = E_INVALIDARG;
}
catch( const std::out_of_range& ) // is a logic_error
{
hr = E_INVALIDARG;
}
catch( const std::length_error& ) // is a logic_error
{
hr = __HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
}
catch( const std::overflow_error& ) // is a runtime_error
{
hr = __HRESULT_FROM_WIN32( ERROR_ARITHMETIC_OVERFLOW );
}
catch( const std::underflow_error& ) // is a runtime_error
{
hr = RPC_S_FP_UNDERFLOW;
}
catch( const std::range_error& ) // is a runtime_error
{
hr = E_INVALIDARG;
}
catch ( const std::logic_error& ) // is an exception
{
hr = E_UNEXPECTED;
}
catch ( const std::runtime_error& ) // is an exception
{
hr = E_FAIL;
}
catch ( const std::exception& ) // base class for standard C++ exceptions
{
hr = E_FAIL;
}
catch ( Platform::Exception^ exception )
{
hr = (HRESULT)exception->HResult;
}
catch ( HRESULT exceptionHR )
{
hr = exceptionHR;
}
catch (...) // everything else
{
hr = E_FAIL;
}
return hr;
}
Platform::String^ ErrorUtils::ConvertHResultToString( HRESULT hr )
{
WCHAR tmp[ 1024 ];
_snwprintf_s( tmp, _countof( tmp ), _TRUNCATE, L"0x%0.8x", hr);
return ref new Platform::String(tmp);
}
Platform::String^ ErrorUtils::ConvertHResultToErrorName( HRESULT hr )
{
switch( hr )
{
// Generic errors
case S_OK: return L"S_OK";
case S_FALSE: return L"S_FALSE";
case E_OUTOFMEMORY: return L"E_OUTOFMEMORY";
case E_ACCESSDENIED: return L"E_ACCESSDENIED";
case E_INVALIDARG: return L"E_INVALIDARG";
case E_UNEXPECTED: return L"E_UNEXPECTED";
case E_ABORT: return L"E_ABORT";
case E_FAIL: return L"E_FAIL";
case E_NOTIMPL: return L"E_NOTIMPL";
case E_ILLEGAL_METHOD_CALL: return L"E_ILLEGAL_METHOD_CALL";
// Authentication specific errors
case 0x87DD0003: return L"AM_E_XASD_UNEXPECTED";
case 0x87DD0004: return L"AM_E_XASU_UNEXPECTED";
case 0x87DD0005: return L"AM_E_XAST_UNEXPECTED";
case 0x87DD0006: return L"AM_E_XSTS_UNEXPECTED";
case 0x87DD0007: return L"AM_E_XDEVICE_UNEXPECTED";
case 0x87DD0008: return L"AM_E_DEVMODE_NOT_AUTHORIZED";
case 0x87DD0009: return L"AM_E_NOT_AUTHORIZED";
case 0x87DD000A: return L"AM_E_FORBIDDEN";
case 0x87DD000B: return L"AM_E_UNKNOWN_TARGET";
case 0x87DD000C: return L"AM_E_NSAL_READ_FAILED";
case 0x87DD000D: return L"AM_E_TITLE_NOT_AUTHENTICATED";
case 0x87DD000E: return L"AM_E_TITLE_NOT_AUTHORIZED";
case 0x87DD000F: return L"AM_E_DEVICE_NOT_AUTHENTICATED";
case 0x87DD0010: return L"AM_E_INVALID_USER_INDEX";
case 0x8015DC00: return L"XO_E_DEVMODE_NOT_AUTHORIZED";
case 0x8015DC01: return L"XO_E_SYSTEM_UPDATE_REQUIRED";
case 0x8015DC02: return L"XO_E_CONTENT_UPDATE_REQUIRED";
case 0x8015DC03: return L"XO_E_ENFORCEMENT_BAN";
case 0x8015DC04: return L"XO_E_THIRD_PARTY_BAN";
case 0x8015DC05: return L"XO_E_ACCOUNT_PARENTALLY_RESTRICTED";
case 0x8015DC06: return L"XO_E_DEVICE_SUBSCRIPTION_NOT_ACTIVATED";
case 0x8015DC08: return L"XO_E_ACCOUNT_BILLING_MAINTENANCE_REQUIRED";
case 0x8015DC09: return L"XO_E_ACCOUNT_CREATION_REQUIRED";
case 0x8015DC0A: return L"XO_E_ACCOUNT_TERMS_OF_USE_NOT_ACCEPTED";
case 0x8015DC0B: return L"XO_E_ACCOUNT_COUNTRY_NOT_AUTHORIZED";
case 0x8015DC0C: return L"XO_E_ACCOUNT_AGE_VERIFICATION_REQUIRED";
case 0x8015DC0D: return L"XO_E_ACCOUNT_CURFEW";
case 0x8015DC0E: return L"XO_E_ACCOUNT_ZEST_MAINTENANCE_REQUIRED";
case 0x8015DC0F: return L"XO_E_ACCOUNT_CSV_TRANSITION_REQUIRED";
case 0x8015DC10: return L"XO_E_ACCOUNT_MAINTENANCE_REQUIRED";
case 0x8015DC11: return L"XO_E_ACCOUNT_TYPE_NOT_ALLOWED";
case 0x8015DC12: return L"XO_E_CONTENT_ISOLATION (Verify SCID / Sandbox)";
case 0x8015DC13: return L"XO_E_ACCOUNT_NAME_CHANGE_REQUIRED";
case 0x8015DC14: return L"XO_E_DEVICE_CHALLENGE_REQUIRED";
case 0x8015DC20: return L"XO_E_EXPIRED_DEVICE_TOKEN";
case 0x8015DC21: return L"XO_E_EXPIRED_TITLE_TOKEN";
case 0x8015DC22: return L"XO_E_EXPIRED_USER_TOKEN";
case 0x8015DC23: return L"XO_E_INVALID_DEVICE_TOKEN";
case 0x8015DC24: return L"XO_E_INVALID_TITLE_TOKEN";
case 0x8015DC25: return L"XO_E_INVALID_USER_TOKEN";
// HTTP specific errors
case WEB_E_UNSUPPORTED_FORMAT: return L"WEB_E_UNSUPPORTED_FORMAT";
case WEB_E_INVALID_XML: return L"WEB_E_INVALID_XML";
case WEB_E_MISSING_REQUIRED_ELEMENT: return L"WEB_E_MISSING_REQUIRED_ELEMENT";
case WEB_E_MISSING_REQUIRED_ATTRIBUTE: return L"WEB_E_MISSING_REQUIRED_ATTRIBUTE";
case WEB_E_UNEXPECTED_CONTENT: return L"WEB_E_UNEXPECTED_CONTENT";
case WEB_E_RESOURCE_TOO_LARGE: return L"WEB_E_RESOURCE_TOO_LARGE";
case WEB_E_INVALID_JSON_STRING: return L"WEB_E_INVALID_JSON_STRING";
case WEB_E_INVALID_JSON_NUMBER: return L"WEB_E_INVALID_JSON_NUMBER";
case WEB_E_JSON_VALUE_NOT_FOUND: return L"WEB_E_JSON_VALUE_NOT_FOUND";
case HTTP_E_STATUS_UNEXPECTED: return L"HTTP_E_STATUS_UNEXPECTED";
case HTTP_E_STATUS_UNEXPECTED_REDIRECTION: return L"HTTP_E_STATUS_UNEXPECTED_REDIRECTION";
case HTTP_E_STATUS_UNEXPECTED_CLIENT_ERROR: return L"HTTP_E_STATUS_UNEXPECTED_CLIENT_ERROR";
case HTTP_E_STATUS_UNEXPECTED_SERVER_ERROR: return L"HTTP_E_STATUS_UNEXPECTED_SERVER_ERROR";
case HTTP_E_STATUS_AMBIGUOUS: return L"HTTP_E_STATUS_AMBIGUOUS";
case HTTP_E_STATUS_MOVED: return L"HTTP_E_STATUS_MOVED";
case HTTP_E_STATUS_REDIRECT: return L"HTTP_E_STATUS_REDIRECT";
case HTTP_E_STATUS_REDIRECT_METHOD: return L"HTTP_E_STATUS_REDIRECT_METHOD";
case HTTP_E_STATUS_NOT_MODIFIED: return L"HTTP_E_STATUS_NOT_MODIFIED";
case HTTP_E_STATUS_USE_PROXY: return L"HTTP_E_STATUS_USE_PROXY";
case HTTP_E_STATUS_REDIRECT_KEEP_VERB: return L"HTTP_E_STATUS_REDIRECT_KEEP_VERB";
case HTTP_E_STATUS_BAD_REQUEST: return L"HTTP_E_STATUS_BAD_REQUEST";
case HTTP_E_STATUS_DENIED: return L"HTTP_E_STATUS_DENIED";
case HTTP_E_STATUS_PAYMENT_REQ: return L"HTTP_E_STATUS_PAYMENT_REQ";
case HTTP_E_STATUS_FORBIDDEN: return L"HTTP_E_STATUS_FORBIDDEN";
case HTTP_E_STATUS_NOT_FOUND: return L"HTTP_E_STATUS_NOT_FOUND";
case HTTP_E_STATUS_BAD_METHOD: return L"HTTP_E_STATUS_BAD_METHOD";
case HTTP_E_STATUS_NONE_ACCEPTABLE: return L"HTTP_E_STATUS_NONE_ACCEPTABLE";
case HTTP_E_STATUS_PROXY_AUTH_REQ: return L"HTTP_E_STATUS_PROXY_AUTH_REQ";
case HTTP_E_STATUS_REQUEST_TIMEOUT: return L"HTTP_E_STATUS_REQUEST_TIMEOUT";
case HTTP_E_STATUS_CONFLICT: return L"HTTP_E_STATUS_CONFLICT";
case HTTP_E_STATUS_GONE: return L"HTTP_E_STATUS_GONE";
case HTTP_E_STATUS_LENGTH_REQUIRED: return L"HTTP_E_STATUS_LENGTH_REQUIRED";
case HTTP_E_STATUS_PRECOND_FAILED: return L"HTTP_E_STATUS_PRECOND_FAILED";
case HTTP_E_STATUS_REQUEST_TOO_LARGE: return L"HTTP_E_STATUS_REQUEST_TOO_LARGE";
case HTTP_E_STATUS_URI_TOO_LONG: return L"HTTP_E_STATUS_URI_TOO_LONG";
case HTTP_E_STATUS_UNSUPPORTED_MEDIA: return L"HTTP_E_STATUS_UNSUPPORTED_MEDIA";
case HTTP_E_STATUS_RANGE_NOT_SATISFIABLE: return L"HTTP_E_STATUS_RANGE_NOT_SATISFIABLE";
case HTTP_E_STATUS_EXPECTATION_FAILED: return L"HTTP_E_STATUS_EXPECTATION_FAILED";
case HTTP_E_STATUS_SERVER_ERROR: return L"HTTP_E_STATUS_SERVER_ERROR";
case HTTP_E_STATUS_NOT_SUPPORTED: return L"HTTP_E_STATUS_NOT_SUPPORTED";
case HTTP_E_STATUS_BAD_GATEWAY: return L"HTTP_E_STATUS_BAD_GATEWAY";
case HTTP_E_STATUS_SERVICE_UNAVAIL: return L"HTTP_E_STATUS_SERVICE_UNAVAIL";
case HTTP_E_STATUS_GATEWAY_TIMEOUT: return L"HTTP_E_STATUS_GATEWAY_TIMEOUT";
case HTTP_E_STATUS_VERSION_NOT_SUP: return L"HTTP_E_STATUS_VERSION_NOT_SUP";
// WinINet specific errors
case INET_E_INVALID_URL: return L"INET_E_INVALID_URL";
case INET_E_NO_SESSION: return L"INET_E_NO_SESSION";
case INET_E_CANNOT_CONNECT: return L"INET_E_CANNOT_CONNECT";
case INET_E_RESOURCE_NOT_FOUND: return L"INET_E_RESOURCE_NOT_FOUND";
case INET_E_OBJECT_NOT_FOUND: return L"INET_E_OBJECT_NOT_FOUND";
case INET_E_DATA_NOT_AVAILABLE: return L"INET_E_DATA_NOT_AVAILABLE";
case INET_E_DOWNLOAD_FAILURE: return L"INET_E_DOWNLOAD_FAILURE";
case INET_E_AUTHENTICATION_REQUIRED: return L"INET_E_AUTHENTICATION_REQUIRED";
case INET_E_NO_VALID_MEDIA: return L"INET_E_NO_VALID_MEDIA";
case INET_E_CONNECTION_TIMEOUT: return L"INET_E_CONNECTION_TIMEOUT";
case INET_E_INVALID_REQUEST: return L"INET_E_INVALID_REQUEST";
case INET_E_UNKNOWN_PROTOCOL: return L"INET_E_UNKNOWN_PROTOCOL";
case INET_E_SECURITY_PROBLEM: return L"INET_E_SECURITY_PROBLEM";
case INET_E_CANNOT_LOAD_DATA: return L"INET_E_CANNOT_LOAD_DATA";
case INET_E_CANNOT_INSTANTIATE_OBJECT: return L"INET_E_CANNOT_INSTANTIATE_OBJECT";
case INET_E_INVALID_CERTIFICATE: return L"INET_E_INVALID_CERTIFICATE";
case INET_E_REDIRECT_FAILED: return L"INET_E_REDIRECT_FAILED";
case INET_E_REDIRECT_TO_DIR: return L"INET_E_REDIRECT_TO_DIR";
}
return L"Unknown error";
}
}}}
#endif
+38
View File
@@ -0,0 +1,38 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
private class ErrorUtils
{
public:
/// <summary>
/// Converts HTTP status Code (e.g., 200, 401, 304) to HRESULT
/// </summary>
static HRESULT
ConvertHttpStatusCodeToHR(
_In_ uint32 HttpStatusCode
);
static HRESULT
ConvertExceptionToHRESULT();
static Platform::String^
ConvertHResultToString( HRESULT hr );
static Platform::String^
ConvertHResultToErrorName( HRESULT hr );
};
}}}
#endif
+31
View File
@@ -0,0 +1,31 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "FactoryCache.h"
#include "StringUtils.h"
#if TV_API
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
namespace Microsoft {
namespace Xbox {
namespace GameChat {
FactoryCache::FactoryCache()
{
HRESULT hr;
hr = Windows::Foundation::GetActivationFactory( Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_Streams_Buffer ).Get(), &m_bufferFactory );
CHAT_THROW_IF_HR_FAILED( hr );
CHAT_THROW_E_POINTER_IF_NULL( m_bufferFactory );
}
}}}
#endif
+31
View File
@@ -0,0 +1,31 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
class FactoryCache
{
public:
FactoryCache();
inline Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> GetBufferFactory()
{
return m_bufferFactory;
}
private:
Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> m_bufferFactory;
};
}}}
#endif
+89
View File
@@ -0,0 +1,89 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "StringUtils.h"
#include "ErrorUtils.h"
#if TV_API
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;
namespace Microsoft {
namespace Xbox {
namespace GameChat {
Platform::String^
StringUtils::GetLogExceptionDebugInfo(
_In_ HRESULT hr,
_In_opt_ PCWSTR pwszFunction,
_In_opt_ PCWSTR pwszFile,
_In_ uint32 uLine
)
{
std::wstring info = L"[Exception]: HRESULT: ";
info += ErrorUtils::ConvertHResultToString(hr)->Data();
info += L"\n";
if( pwszFunction != nullptr )
{
info += L"\t\tFunction: ";
info += pwszFunction;
info += L"\n";
}
if( pwszFile != nullptr )
{
info += L"\t\tFile:";
info += pwszFile;
info += L"(";
info += uLine.ToString()->Data();
info += L")\n";
}
return ref new Platform::String( info.c_str() );
}
bool StringUtils::IsStringEqualCaseInsenstive(
_In_ Platform::String^ val1,
_In_ Platform::String^ val2
)
{
return ( _wcsicmp(val1->Data(), val2->Data()) == 0 );
}
Platform::String^
StringUtils::GetStringFormat(
_In_ LPCWSTR strMsg,
_In_ va_list args
)
{
WCHAR strBuffer[2048];
_vsnwprintf_s( strBuffer, 2048, _TRUNCATE, strMsg, args );
strBuffer[2047] = L'\0';
return ref new Platform::String(strBuffer);
}
Platform::String^
StringUtils::FormatString( LPCWSTR strMsg, ... )
{
WCHAR strBuffer[2048];
va_list args;
va_start(args, strMsg);
_vsnwprintf_s( strBuffer, 2048, _TRUNCATE, strMsg, args );
strBuffer[2047] = L'\0';
va_end(args);
Platform::String^ str = ref new Platform::String(strBuffer);
return str;
}
}}}
#endif
+43
View File
@@ -0,0 +1,43 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
private class StringUtils
{
public:
static Platform::String^
GetLogExceptionDebugInfo(
_In_ HRESULT hr,
_In_opt_ PCWSTR pwszFunction,
_In_opt_ PCWSTR pwszFile,
_In_ uint32 uLine
);
static bool IsStringEqualCaseInsenstive(
_In_ Platform::String^ val1,
_In_ Platform::String^ val2
);
static Platform::String^
GetStringFormat(
_In_ LPCWSTR strMsg,
_In_ va_list args
);
static Platform::String^
FormatString( LPCWSTR strMsg, ... );
};
}}}
#endif
+132
View File
@@ -0,0 +1,132 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include "pch.h"
#include "Thread.h"
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
Thread::Thread(
_In_ UINT workPeriodInMilliseconds,
_In_ int32 threadAffinityMask,
_In_ int threadPriority
) :
m_threadPriority(threadPriority),
m_workPeriodInMilliseconds(workPeriodInMilliseconds),
m_terminateThreadEvent(nullptr),
m_threadAffinityMask(threadAffinityMask),
m_threadHandle(nullptr),
m_wakeupEventHandle(nullptr)
{
m_wakeupEventHandle = CreateEvent( nullptr, false, false, nullptr );
InitializeCriticalSection(&m_threadManagementLock);
m_terminateThreadEvent = CreateEvent( nullptr, false, false, nullptr );
if ( !m_terminateThreadEvent )
{
throw E_UNEXPECTED;
}
m_threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)Thread::StaticThreadProc, (LPVOID)this, CREATE_SUSPENDED, nullptr);
if ( !m_threadHandle )
{
throw HRESULT_FROM_WIN32( GetLastError() );
}
SetThreadPriority(m_threadHandle, m_threadPriority);
#if WINAPI_FAMILY == WINAPI_FAMILY_TV_TITLE
SetThreadAffinityMask(m_threadHandle, m_threadAffinityMask);
#endif
ResumeThread(m_threadHandle);
}
Thread::~Thread()
{
Shutdown();
DeleteCriticalSection(&m_threadManagementLock);
}
UINT Thread::GetWorkPeriodInMilliseconds()
{
return m_workPeriodInMilliseconds;
}
void Thread::SetWorkPeriodInMilliseconds(
_In_ UINT sendPeriodInMilliseconds
)
{
m_workPeriodInMilliseconds = sendPeriodInMilliseconds;
m_clock.SetInterval(m_workPeriodInMilliseconds);
}
void Thread::SetOptions(
_In_ int32 threadAffinityMask,
_In_ int threadPriority
)
{
m_threadPriority = threadPriority;
m_threadAffinityMask = threadAffinityMask;
if( m_threadHandle != nullptr )
{
SetThreadPriority(m_threadHandle, m_threadPriority);
#if WINAPI_FAMILY == WINAPI_FAMILY_TV_TITLE
SetThreadAffinityMask(m_threadHandle, m_threadAffinityMask);
#endif
}
}
void Thread::Shutdown()
{
EnterCriticalSection(&m_threadManagementLock);
if( m_threadHandle != nullptr )
{
SetEvent(m_terminateThreadEvent);
WaitForSingleObject(m_threadHandle, INFINITE);
CloseHandle(m_threadHandle);
m_threadHandle = nullptr;
}
LeaveCriticalSection(&m_threadManagementLock);
}
DWORD WINAPI Thread::StaticThreadProc(
_In_ Thread^ networkSendThread
)
{
return networkSendThread->ThreadProc();
}
DWORD WINAPI Thread::ThreadProc()
{
m_clock.Initialize( m_workPeriodInMilliseconds );
static const UINT c_uOneSecondInMS = 1000;
LARGE_INTEGER m_timerFrequency;
QueryPerformanceFrequency(&m_timerFrequency);
while( m_clock.WaitForEventsOrHeartbeat( m_terminateThreadEvent, m_wakeupEventHandle ) != WAIT_OBJECT_0 )
{
OnDoWork();
}
return 0;
}
void Thread::WakeupThread()
{
SetEvent( m_wakeupEventHandle );
}
}}}
#endif
+66
View File
@@ -0,0 +1,66 @@
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "Clock.h"
#if TV_API
namespace Microsoft {
namespace Xbox {
namespace GameChat {
delegate void ThreadDoWorkHandler();
ref class Thread sealed
{
public:
Thread(
_In_ UINT sendPeriodInMilliseconds,
_In_ int32 threadAffinityMask,
_In_ int threadPriority
);
virtual ~Thread();
void Shutdown();
UINT GetWorkPeriodInMilliseconds();
void SetWorkPeriodInMilliseconds(
_In_ UINT sendPeriodInMilliseconds
);
void SetOptions(
_In_ int32 threadAffinityMask,
_In_ int threadPriority
);
void WakeupThread();
event ThreadDoWorkHandler^ OnDoWork;
private:
static DWORD WINAPI StaticThreadProc(
_In_ Thread^ networkSendThread
);
DWORD ThreadProc();
private:
CRITICAL_SECTION m_threadManagementLock;
Clock m_clock;
HANDLE m_terminateThreadEvent;
HANDLE m_threadHandle;
HANDLE m_wakeupEventHandle;
UINT m_workPeriodInMilliseconds;
int m_threadPriority;
uint32 m_threadAffinityMask;
};
}}}
#endif