mirror of
https://github.com/WinDurango/WinDurango.git
synced 2026-05-03 15:59:58 -05:00
Added Keyboard and vkeyboard
This commit is contained in:
@@ -185,4 +185,7 @@ DEFINE_GUID(DXGI_DEBUG_D3D11, 0x4b99317b, 0xac39, 0x4aa6, 0xbb, 0xb, 0xba, 0xa0,
|
||||
#define TRACE_NOT_IMPLEMENTED(class_name) \
|
||||
MessageBoxA(NULL, std::format("[{}] NOT IMPLEMENTED\n{} - line {}", class_name, __FILE__, __LINE__).c_str(), "WD - d3d11_x", MB_OK) \
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern "C" __declspec(dllexport) void WD11XNotify_X(WDEVENT_TYPE event);
|
||||
extern "C" __declspec(dllexport) void WDWaitForKeyboard(const char** outText);
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
================================================================================
|
||||
DISCLAIMER AND LICENSE REQUIREMENT
|
||||
|
||||
@@ -17,7 +17,7 @@ If you do not agree to these terms, you do not have permission to use this code.
|
||||
================================================================================
|
||||
*/
|
||||
#include "overlay.h"
|
||||
|
||||
#define IMGUI_USE_WCHAR32
|
||||
#include "../../../thirdparty/imgui/imgui.h"
|
||||
#include "../../../thirdparty/imgui/backends/imgui_impl_dx11.h"
|
||||
#include "../../../thirdparty/imgui_impl_uwp.h"
|
||||
@@ -66,7 +66,16 @@ void wd::Overlay::Initialize( )
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
|
||||
io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
||||
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
||||
|
||||
ImFontConfig config;
|
||||
config.MergeMode = true;
|
||||
|
||||
static const ImWchar icon_ranges[] = { 0xE000, 0xF8FF, 0 };
|
||||
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segmdl2.ttf", 25.0f, &config, icon_ranges);
|
||||
|
||||
// 3️⃣ Build the font atlas
|
||||
io.Fonts->Build( );
|
||||
ImGui::StyleColorsDark( );
|
||||
|
||||
ImGui_ImplUwp_InitForCurrentView( );
|
||||
@@ -239,16 +248,18 @@ void wd::Overlay::Present( )
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData( ));
|
||||
}
|
||||
|
||||
void wd::Overlay::RenderKeyboardWindow( )
|
||||
static int cursorPos = 0;
|
||||
|
||||
void wd::Overlay::RenderKeyboardWindow()
|
||||
{
|
||||
static bool isUppercase = false;
|
||||
static bool isSymbols = false;
|
||||
|
||||
const char* keys[] = {
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]",
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'",
|
||||
"Z", "X", "C", "V", "B", "N", "M", ",", ".", "/"
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "'",
|
||||
"Z", "X", "C", "V", "B", "N", "M", ",", ".", "?"
|
||||
};
|
||||
|
||||
const char* symbols[] = {
|
||||
@@ -260,34 +271,250 @@ void wd::Overlay::RenderKeyboardWindow( )
|
||||
const char** currentKeys = isSymbols ? symbols : keys;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO( );
|
||||
ImGui::SetNextWindowSize(ImVec2(500, 330));
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
ImGui::Begin("WinDurango Keyboard", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
||||
ImVec2 displaySize = ImGui::GetIO( ).DisplaySize;
|
||||
|
||||
ImGui::InputText(" ", g_KeyboardText, IM_ARRAYSIZE(g_KeyboardText));
|
||||
ImGui::SetNextWindowPos(ImVec2(displaySize.x / 2, displaySize.y / 2), ImGuiCond_Always);
|
||||
|
||||
if (ImGui::Button(isUppercase ? "Lowercase" : "Uppercase"))
|
||||
isUppercase = !isUppercase;
|
||||
ImGui::SameLine( );
|
||||
if (ImGui::Button(isSymbols ? "Letters" : "Symbols"))
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar;
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, IM_COL32(0x05, 0x05, 0x05, 0xFF));
|
||||
ImGui::Begin("Keyboard", nullptr, windowFlags);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0x37, 0x37, 0x37, 0xFF));
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0x05, 0x05, 0x05, 0xFF));
|
||||
ImGui::InputText("", g_KeyboardText, IM_ARRAYSIZE(g_KeyboardText), ImGuiInputTextFlags_CallbackAlways,
|
||||
[](ImGuiInputTextCallbackData* data) -> int {
|
||||
data->CursorPos = cursorPos;
|
||||
return 0;
|
||||
});
|
||||
ImGui::PopStyleColor( );
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3));
|
||||
|
||||
if (ImGui::Button("##symb", ImVec2(60, 30)))
|
||||
isSymbols = !isSymbols;
|
||||
|
||||
ImGui::NewLine( );
|
||||
RenderKeyboardRow(currentKeys, 0, 12, isUppercase);
|
||||
RenderKeyboardRow(currentKeys, 12, 24, isUppercase);
|
||||
if (!isSymbols) RenderKeyboardRow(currentKeys, 24, 35, isUppercase);
|
||||
else RenderKeyboardRow(currentKeys, 24, 32, isUppercase);
|
||||
if (!isSymbols) RenderKeyboardRow(currentKeys, 35, 44, isUppercase);
|
||||
ImVec2 pos = ImGui::GetItemRectMin( );
|
||||
ImVec2 size = ImGui::GetItemRectSize( );
|
||||
|
||||
ImGui::NewLine( );
|
||||
HandleKeyboardSpecialKeys( );
|
||||
if (!isSymbols) {
|
||||
ImVec2 textSize = ImGui::CalcTextSize("#+=");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), ImGui::GetFontSize( ),
|
||||
ImVec2((pos.x + (size.x - textSize.x) * 0.5f) - 10, pos.y + (size.y - textSize.y) * 0.5f),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"#+="
|
||||
);
|
||||
} else {
|
||||
ImVec2 textSize = ImGui::CalcTextSize("ABC");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), ImGui::GetFontSize( ),
|
||||
ImVec2((pos.x + (size.x - textSize.x) * 0.5f) - 10, pos.y + (size.y - textSize.y) * 0.5f),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"ABC"
|
||||
);
|
||||
}
|
||||
|
||||
ImVec2 iconSize = ImGui::CalcTextSize("\xEF\x84\x8A");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 12,
|
||||
ImVec2((pos.x + (size.x - iconSize.x) * 0.5f) + 18, (pos.y + (size.y - iconSize.y) * 0.5f) + 8),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEF\x84\x8A"
|
||||
);
|
||||
|
||||
ImGui::SameLine();
|
||||
RenderKeyboardRow(currentKeys, 0, 10, isUppercase);
|
||||
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3));
|
||||
ImGui::SameLine( );
|
||||
if (ImGui::Button("##del", ImVec2(60, 30)) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Backspace) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_GamepadFaceLeft)) {
|
||||
size_t len = strlen(g_KeyboardText);
|
||||
if (len > 0)
|
||||
g_KeyboardText[ len - 1 ] = '\0';
|
||||
}
|
||||
ImVec2 posa = ImGui::GetItemRectMin( );
|
||||
ImVec2 sizea = ImGui::GetItemRectSize( );
|
||||
|
||||
ImVec2 textSizea = ImGui::CalcTextSize("\xEE\x9D\x90");
|
||||
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ),
|
||||
14,
|
||||
ImVec2((posa.x + (sizea.x - textSizea.x) * 0.5f) - 6, (posa.y + (sizea.y - textSizea.y) * 0.5f) + 7),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\x9D\x90"
|
||||
);
|
||||
|
||||
textSizea = ImGui::CalcTextSize("\xEF\x82\x96");
|
||||
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ),
|
||||
10,
|
||||
ImVec2((posa.x + (sizea.x - textSizea.x) * 0.5f) + 18, (posa.y + (sizea.y - textSizea.y) * 0.5f) + 8),
|
||||
IM_COL32(0, 149, 209, 255),
|
||||
"\xEF\x82\x96"
|
||||
);
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3));
|
||||
|
||||
if (ImGui::Button("##bac", ImVec2(60.0f, 63)) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_LeftShift) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_GamepadL1))
|
||||
cursorPos = max(0, cursorPos - 1);
|
||||
|
||||
pos = ImGui::GetItemRectMin( );
|
||||
size = ImGui::GetItemRectSize( );
|
||||
|
||||
ImFont* bigFont = ImGui::GetFont( );
|
||||
float bigFontSize = 18.0f;
|
||||
ImVec2 bigTextSize = ImGui::CalcTextSize("\xEE\xA5\xAF");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
bigFont, bigFontSize,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\x80\x8E"
|
||||
);
|
||||
|
||||
ImFont* smallFont = bigFont;
|
||||
float smallFontSize = 14.0f;
|
||||
ImVec2 smallTextSize = ImGui::CalcTextSize("\xEF\x84\x8C");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
smallFont, smallFontSize,
|
||||
ImVec2(pos.x + (size.x - smallTextSize.x) * 0.5f, pos.y + 26 + bigTextSize.y),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEF\x84\x8C"
|
||||
);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImVec2 currPos = ImGui::GetCursorPos( );
|
||||
RenderKeyboardRow(currentKeys, 10, 20, isUppercase);
|
||||
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3));
|
||||
ImGui::SameLine( );
|
||||
ImGui::SetWindowFontScale(1.5f);
|
||||
if (ImGui::Button("##for", ImVec2(60.0f, 63)))
|
||||
cursorPos++;
|
||||
|
||||
pos = ImGui::GetItemRectMin( );
|
||||
size = ImGui::GetItemRectSize( );
|
||||
|
||||
bigTextSize = ImGui::CalcTextSize("\xEE\x80\x8F");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 18,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 6, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\x80\x8F"
|
||||
);
|
||||
|
||||
smallTextSize = ImGui::CalcTextSize("\xEF\x84\x8D");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 14,
|
||||
ImVec2((pos.x + (size.x - smallTextSize.x) * 0.5f) + 8, pos.y + 20 + bigTextSize.y),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEF\x84\x8D"
|
||||
);
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3));
|
||||
|
||||
ImVec2 row2Pos = ImGui::GetCursorPos( );
|
||||
row2Pos.x = currPos.x;
|
||||
row2Pos.y -= 33;
|
||||
ImGui::SetCursorPos(row2Pos);
|
||||
if (!isSymbols) RenderKeyboardRow(currentKeys, 20, 30, isUppercase);
|
||||
else RenderKeyboardRow(currentKeys, 20, 30, isUppercase);
|
||||
|
||||
if (ImGui::Button("##upper", ImVec2(60.0f, 63)))
|
||||
isUppercase = !isUppercase;
|
||||
|
||||
pos = ImGui::GetItemRectMin( );
|
||||
size = ImGui::GetItemRectSize( );
|
||||
|
||||
if (!isUppercase) {
|
||||
bigTextSize = ImGui::CalcTextSize("\xEE\x9D\x92");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 18,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\x9D\x92"
|
||||
);
|
||||
} else {
|
||||
bigTextSize = ImGui::CalcTextSize("\xEE\xA2\x96");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 18,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\xA2\x96"
|
||||
);
|
||||
}
|
||||
|
||||
smallTextSize = ImGui::CalcTextSize("\xEF\x84\x88");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 14,
|
||||
ImVec2(pos.x + (size.x - smallTextSize.x) * 0.5f, pos.y + 26 + bigTextSize.y),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEF\x84\x88"
|
||||
);
|
||||
|
||||
ImGui::SameLine( );
|
||||
currPos = ImGui::GetCursorPos( );
|
||||
if (!isSymbols) RenderKeyboardRow(currentKeys, 30, 40, isUppercase);
|
||||
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3));
|
||||
ImGui::SameLine( );
|
||||
if (ImGui::Button("##enter", ImVec2(60.0f, 63)) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_GamepadStart)) {
|
||||
m_bKeyboard = false;
|
||||
SetEvent(g_KeyboardFinished);
|
||||
cursorPos = 0;
|
||||
}
|
||||
pos = ImGui::GetItemRectMin( );
|
||||
size = ImGui::GetItemRectSize( );
|
||||
|
||||
bigTextSize = ImGui::CalcTextSize("\xEE\xAF\xA7");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 18,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 2, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\xAF\xA7"
|
||||
);
|
||||
|
||||
smallTextSize = ImGui::CalcTextSize("\xEE\xB7\xA3");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 12,
|
||||
ImVec2((pos.x + (size.x - smallTextSize.x) * 0.5f) + 5, pos.y + 26 + bigTextSize.y),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\xB7\xA3"
|
||||
);
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
row2Pos = ImGui::GetCursorPos( );
|
||||
row2Pos.x = currPos.x;
|
||||
row2Pos.y -= 33;
|
||||
ImGui::SetCursorPos(row2Pos);
|
||||
|
||||
HandleKeyboardSpecialKeys();
|
||||
|
||||
ImGui::PopStyleVar( );
|
||||
ImGui::PopStyleColor( );
|
||||
ImGui::End( );
|
||||
ImGui::PopStyleColor( );
|
||||
}
|
||||
|
||||
void wd::Overlay::RenderKeyboardRow(const char** keys, int start, int end, bool isUppercase)
|
||||
{
|
||||
ImVec2 buttonSize(30, 30);
|
||||
ImVec2 buttonSize(45, 30);
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
ImGui::PushID(i);
|
||||
@@ -302,36 +529,40 @@ void wd::Overlay::RenderKeyboardRow(const char** keys, int start, int end, bool
|
||||
void wd::Overlay::AddKeyToBuffer(char c)
|
||||
{
|
||||
size_t len = strlen(g_KeyboardText);
|
||||
if (len < 255)
|
||||
{
|
||||
g_KeyboardText[ len ] = c;
|
||||
g_KeyboardText[ len + 1 ] = '\0';
|
||||
}
|
||||
if (len >= 255 || cursorPos > len)
|
||||
return;
|
||||
|
||||
for (size_t i = len; i > cursorPos; --i)
|
||||
g_KeyboardText[ i ] = g_KeyboardText[ i - 1 ];
|
||||
|
||||
g_KeyboardText[ cursorPos ] = c;
|
||||
g_KeyboardText[ len + 1 ] = '\0';
|
||||
cursorPos++;
|
||||
}
|
||||
|
||||
void wd::Overlay::HandleKeyboardSpecialKeys( )
|
||||
{
|
||||
ImVec2 buttonSize(30, 30);
|
||||
|
||||
if (ImGui::Button("Space", ImVec2(60, 30)) || ImGui::IsKeyPressed(ImGuiKey_Space) || ImGui::IsKeyPressed(ImGuiKey_GamepadFaceUp))
|
||||
if (ImGui::Button("##space", ImVec2((ImGui::GetContentRegionAvail().x - 63), 30)) || ImGui::IsKeyPressed(ImGuiKey_GamepadFaceUp))
|
||||
AddKeyToBuffer(' ');
|
||||
ImGui::SameLine( );
|
||||
|
||||
if (ImGui::Button("Backspace", ImVec2(90, 30)) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Backspace) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_GamepadFaceLeft))
|
||||
{
|
||||
size_t len = strlen(g_KeyboardText);
|
||||
if (len > 0)
|
||||
g_KeyboardText[ len - 1 ] = '\0';
|
||||
}
|
||||
ImGui::SameLine( );
|
||||
ImVec2 pos = ImGui::GetItemRectMin( );
|
||||
ImVec2 size = ImGui::GetItemRectSize( );
|
||||
|
||||
if (ImGui::Button("OK", buttonSize) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Enter) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_GamepadStart))
|
||||
{
|
||||
m_bKeyboard = false;
|
||||
SetEvent(g_KeyboardFinished);
|
||||
}
|
||||
ImVec2 bigTextSize = ImGui::CalcTextSize("\xEE\x9D\x9D");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 18,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 18, pos.y + 18),
|
||||
IM_COL32(255, 255, 255, 255),
|
||||
"\xEE\x9D\x9D"
|
||||
);
|
||||
|
||||
ImVec2 smallTextSize = ImGui::CalcTextSize("\xEF\x82\x95");
|
||||
ImGui::GetWindowDrawList( )->AddText(
|
||||
ImGui::GetFont( ), 14,
|
||||
ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 12, pos.y + 14),
|
||||
IM_COL32(250, 161, 25, 255),
|
||||
"\xEF\x82\x95"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,210 +1,448 @@
|
||||
#include "pch.h"
|
||||
#include "CoreApplicationWrapperX.h"
|
||||
#include "FrameworkViewSourceWrapper.h"
|
||||
|
||||
using namespace ABI::Windows::ApplicationModel::Core;
|
||||
|
||||
// ============================================================================
|
||||
// ICoreApplicationExit Implementation
|
||||
// ============================================================================
|
||||
|
||||
HRESULT CoreApplicationWrapperX::Exit()
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ICoreApplicationExit::Exit() called — forwarding to realExit.\n");
|
||||
printf("[CoreApplicationWrapperX] ICoreApplicationExit::Exit() called — forwarding to realExit.\n");
|
||||
|
||||
if (realExit) {
|
||||
return realExit->Exit();
|
||||
}
|
||||
if (!realExit)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: realExit is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
printf("[CoreApplicationWrapperX] WARNING: realExit is null!\n");
|
||||
return E_FAIL;
|
||||
HRESULT hr = realExit->Exit();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] Exit() failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::add_Exiting(__FIEventHandler_1_IInspectable* handler, EventRegistrationToken* token)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] add_Exiting called\n");
|
||||
return realExit ? realExit->add_Exiting(handler, token) : E_FAIL;
|
||||
printf("[CoreApplicationWrapperX] add_Exiting called\n");
|
||||
|
||||
if (!realExit)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: realExit is null in add_Exiting!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return realExit->add_Exiting(handler, token);
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::remove_Exiting(EventRegistrationToken token)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] remove_Exiting called\n");
|
||||
return realExit ? realExit->remove_Exiting(token) : E_FAIL;
|
||||
printf("[CoreApplicationWrapperX] remove_Exiting called\n");
|
||||
|
||||
if (!realExit)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: realExit is null in remove_Exiting!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return realExit->remove_Exiting(token);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// IInspectable Implementation
|
||||
// ============================================================================
|
||||
|
||||
HRESULT CoreApplicationWrapperX::GetIids(ULONG* iidCount, IID** iids)
|
||||
{
|
||||
printf("GetIids\n");
|
||||
return m_realFactory->GetIids(iidCount, iids);
|
||||
printf("[CoreApplicationWrapperX] GetIids\n");
|
||||
|
||||
if (!iidCount || !iids)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realFactory)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realFactory is null in GetIids!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realFactory->GetIids(iidCount, iids);
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::GetRuntimeClassName(HSTRING* className)
|
||||
{
|
||||
printf("GetRuntimeClassName\n");
|
||||
return m_realFactory->GetRuntimeClassName(className);
|
||||
printf("[CoreApplicationWrapperX] GetRuntimeClassName\n");
|
||||
|
||||
if (!className)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realFactory)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realFactory is null in GetRuntimeClassName!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realFactory->GetRuntimeClassName(className);
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::GetTrustLevel(TrustLevel* trustLevel)
|
||||
{
|
||||
printf("GetTrustLevel\n");
|
||||
return m_realFactory->GetTrustLevel(trustLevel);
|
||||
printf("[CoreApplicationWrapperX] GetTrustLevel\n");
|
||||
|
||||
if (!trustLevel)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realFactory)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realFactory is null in GetTrustLevel!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realFactory->GetTrustLevel(trustLevel);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ICoreApplicationX Implementation (Resuming/Suspending)
|
||||
// ============================================================================
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_add_Resuming(__FIEventHandler_1_IInspectable* handler, EventRegistrationToken* token)
|
||||
{
|
||||
printf("_abi_add_Resuming\n");
|
||||
//return m_realCoreApplication->add_Resuming(handler, token);
|
||||
return S_OK;
|
||||
printf("[CoreApplicationWrapperX] _abi_add_Resuming\n");
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Actually forward the call - don't just return S_OK
|
||||
return m_realCoreApplication->add_Resuming(handler, token);
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_remove_Resuming(EventRegistrationToken token)
|
||||
{
|
||||
printf("_abi_remove_Resuming\n");
|
||||
return m_realCoreApplication->remove_Resuming(token);
|
||||
printf("[CoreApplicationWrapperX] _abi_remove_Resuming\n");
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realCoreApplication->remove_Resuming(token);
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_add_Suspending(__FIEventHandler_1_Windows__CApplicationModel__CSuspendingEventArgs* handler, EventRegistrationToken* token)
|
||||
{
|
||||
printf("_abi_add_Suspending\n");
|
||||
//return m_realCoreApplication->add_Suspending(handler, token);
|
||||
return S_OK;
|
||||
printf("[CoreApplicationWrapperX] _abi_add_Suspending\n");
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Actually forward the call - don't just return S_OK
|
||||
return m_realCoreApplication->add_Suspending(handler, token);
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_remove_Suspending(EventRegistrationToken token)
|
||||
{
|
||||
printf("_abi_remove_Suspending\n");
|
||||
return m_realCoreApplication->remove_Suspending(token);
|
||||
printf("[CoreApplicationWrapperX] _abi_remove_Suspending\n");
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] WARNING: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realCoreApplication->remove_Suspending(token);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ICoreApplicationResourceAvailabilityX Implementation
|
||||
// ============================================================================
|
||||
|
||||
HRESULT CoreApplicationWrapperX::_abi_get_ResourceAvailability(ResourceAvailability* resourceAvailability)
|
||||
{
|
||||
// TODO: Stubbed for now.
|
||||
*resourceAvailability = ResourceAvailability_Full;
|
||||
printf("_abi_get_ResourceAvailability\n");
|
||||
return S_OK;
|
||||
printf("[CoreApplicationWrapperX] _abi_get_ResourceAvailability\n");
|
||||
|
||||
if (!resourceAvailability)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Stubbed: Always return full availability for Xbox
|
||||
*resourceAvailability = ResourceAvailability_Full;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::_abi_add_ResourceAvailabilityChanged(winrt::Windows::Foundation::EventHandler<IInspectable>* handler, EventRegistrationToken* token)
|
||||
{
|
||||
printf("_abi_add_ResourceAvailabilityChanged\n");
|
||||
//Stubbed at this moment.
|
||||
return 0;
|
||||
printf("[CoreApplicationWrapperX] _abi_add_ResourceAvailabilityChanged (stubbed)\n");
|
||||
|
||||
if (!token)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Stubbed: Return a dummy token
|
||||
token->value = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::_abi_remove_ResourceAvailabilityChanged(EventRegistrationToken token)
|
||||
{
|
||||
printf("_abi_remove_ResourceAvailabilityChanged\n");
|
||||
//Stubbed at this moment.
|
||||
return 0;
|
||||
printf("[CoreApplicationWrapperX] _abi_remove_ResourceAvailabilityChanged (stubbed)\n");
|
||||
// Stubbed: Nothing to do
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ICoreApplicationGpuPolicy Implementation
|
||||
// ============================================================================
|
||||
|
||||
HRESULT CoreApplicationWrapperX::get_DisableKinectGpuReservation(bool* pOutValue)
|
||||
{
|
||||
*pOutValue = this->m_KinectGpuReservation;
|
||||
return S_OK;
|
||||
printf("[CoreApplicationWrapperX] get_DisableKinectGpuReservation -> %d\n", m_KinectGpuReservation);
|
||||
|
||||
if (!pOutValue)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
*pOutValue = m_KinectGpuReservation;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CoreApplicationWrapperX::set_DisableKinectGpuReservation(bool value)
|
||||
{
|
||||
this->m_KinectGpuReservation = value;
|
||||
return S_OK;
|
||||
printf("[CoreApplicationWrapperX] set_DisableKinectGpuReservation <- %d\n", value);
|
||||
m_KinectGpuReservation = value;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ICoreApplication Implementation
|
||||
// ============================================================================
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_GetCurrentView(ABI::Windows::ApplicationModel::Core::ICoreApplicationView** value)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ---> _abi_GetCurrentView\n");
|
||||
return m_realCoreApplication->GetCurrentView(value);
|
||||
printf("[CoreApplicationWrapperX] _abi_GetCurrentView\n");
|
||||
|
||||
if (!value)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realCoreApplication->GetCurrentView(value);
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_Run(ABI::Windows::ApplicationModel::Core::IFrameworkViewSource* viewSource)
|
||||
{
|
||||
printf("_abi_Run\n");
|
||||
printf("[CoreApplicationWrapperX] _abi_Run - Wrapping IFrameworkViewSource\n");
|
||||
|
||||
// Wrap the ViewSource and pass it to the original function
|
||||
FrameworkViewSourceWrapper* wrappedViewSource = new FrameworkViewSourceWrapper(viewSource);
|
||||
return m_realCoreApplication->Run(wrappedViewSource);
|
||||
if (!viewSource)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: viewSource is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Wrap the ViewSource and pass it to the original function
|
||||
FrameworkViewSourceWrapper* wrappedViewSource = new FrameworkViewSourceWrapper(viewSource);
|
||||
|
||||
if (!wrappedViewSource)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: Failed to allocate FrameworkViewSourceWrapper!\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
HRESULT hr = m_realCoreApplication->Run(wrappedViewSource);
|
||||
|
||||
// Release our reference (m_realCoreApplication should have AddRef'd if it needs it)
|
||||
wrappedViewSource->Release();
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] Run() failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_get_Id(HSTRING* value)
|
||||
{
|
||||
printf("_abi_get_Id\n");
|
||||
return m_realCoreApplication->get_Id(value);
|
||||
printf("[CoreApplicationWrapperX] _abi_get_Id\n");
|
||||
|
||||
if (!value)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realCoreApplication->get_Id(value);
|
||||
}
|
||||
|
||||
INT32 CoreApplicationWrapperX::_abi_get_Properties(ABI::Windows::Foundation::Collections::IPropertySet** value)
|
||||
{
|
||||
printf("_abi_get_Properties\n");
|
||||
return m_realCoreApplication->get_Properties(value);
|
||||
printf("[CoreApplicationWrapperX] _abi_get_Properties\n");
|
||||
|
||||
if (!value)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realCoreApplication)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] ERROR: m_realCoreApplication is null!\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realCoreApplication->get_Properties(value);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// IUnknown Implementation (QueryInterface, AddRef, Release)
|
||||
// ============================================================================
|
||||
|
||||
HRESULT CoreApplicationWrapperX::QueryInterface(const IID& riid, void** ppvObject)
|
||||
{
|
||||
LPOLESTR str = nullptr;
|
||||
StringFromIID(riid, &str);
|
||||
wprintf(L"CoreApplicationWrapperX [QI] IID Requested: %s\n", str);
|
||||
CoTaskMemFree(str);
|
||||
if (!ppvObject)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IActivationFactory) || riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = static_cast<IActivationFactory*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
*ppvObject = nullptr;
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationX))
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationX*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if (riid == __uuidof(ICoreApplicationExit))
|
||||
{
|
||||
*ppvObject = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if (riid == __uuidof(ICoreApplicationResourceAvailabilityX)) // allow ICoreApplicationResourceAvailabilityX interface
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationResourceAvailabilityX*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
LPOLESTR str = nullptr;
|
||||
if (SUCCEEDED(StringFromIID(riid, &str)))
|
||||
{
|
||||
wprintf(L"CoreApplicationWrapperX [QI] IID Requested: %s\n", str);
|
||||
CoTaskMemFree(str);
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationGpuPolicy)) // allow ICoreApplicationResourceAvailabilityX interface
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationGpuPolicy*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
// Handle our wrapper interfaces first
|
||||
if (riid == __uuidof(IActivationFactory) || riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = static_cast<IActivationFactory*>(this);
|
||||
AddRef();
|
||||
printf(" -> Returning IActivationFactory/IUnknown\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationExit)) {
|
||||
printf("ICoreApplicationExit CALLED - GAME OVER BRO\n");
|
||||
*ppvObject = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if (riid == __uuidof(IInspectable))
|
||||
{
|
||||
// Use IActivationFactory as the path to IInspectable to avoid ambiguity
|
||||
*ppvObject = static_cast<IInspectable*>(static_cast<IActivationFactory*>(this));
|
||||
AddRef();
|
||||
printf(" -> Returning IInspectable\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
HRESULT hr = m_realFactory->QueryInterface(riid, ppvObject);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
|
||||
OLECHAR iidwstr[sizeof(iidstr)];
|
||||
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
|
||||
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
|
||||
MessageBoxA(nullptr, iidstr, typeid(*this).name(), MB_OK);
|
||||
}
|
||||
|
||||
*ppvObject = nullptr;
|
||||
return E_NOINTERFACE;
|
||||
if (riid == __uuidof(ICoreApplicationX))
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationX*>(this);
|
||||
AddRef();
|
||||
printf(" -> Returning ICoreApplicationX\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationExit))
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationExit*>(this);
|
||||
AddRef();
|
||||
printf(" -> Returning ICoreApplicationExit\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationResourceAvailabilityX))
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationResourceAvailabilityX*>(this);
|
||||
AddRef();
|
||||
printf(" -> Returning ICoreApplicationResourceAvailabilityX\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(ICoreApplicationGpuPolicy))
|
||||
{
|
||||
*ppvObject = static_cast<ICoreApplicationGpuPolicy*>(this);
|
||||
AddRef();
|
||||
printf(" -> Returning ICoreApplicationGpuPolicy\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Try delegating to the real factory
|
||||
if (m_realFactory)
|
||||
{
|
||||
HRESULT hr = m_realFactory->QueryInterface(riid, ppvObject);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
printf(" -> Delegated to m_realFactory (SUCCESS)\n");
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" -> Delegated to m_realFactory (FAILED: 0x%08X)\n", hr);
|
||||
}
|
||||
}
|
||||
|
||||
// Show MessageBox for debugging unhandled interfaces
|
||||
char iidstr[64];
|
||||
OLECHAR iidwstr[64];
|
||||
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
|
||||
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
|
||||
|
||||
printf(" -> E_NOINTERFACE for IID: %s\n", iidstr);
|
||||
MessageBoxA(nullptr, iidstr, "CoreApplicationWrapperX - Unhandled Interface", MB_OK | MB_ICONWARNING);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG CoreApplicationWrapperX::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_RefCount);
|
||||
ULONG refCount = InterlockedIncrement(&m_RefCount);
|
||||
printf("[CoreApplicationWrapperX] AddRef() -> %lu\n", refCount);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
ULONG CoreApplicationWrapperX::Release()
|
||||
{
|
||||
ULONG refCount = InterlockedDecrement(&m_RefCount);
|
||||
if (refCount == 0)
|
||||
delete this;
|
||||
return refCount;
|
||||
}
|
||||
ULONG refCount = InterlockedDecrement(&m_RefCount);
|
||||
printf("[CoreApplicationWrapperX] Release() -> %lu\n", refCount);
|
||||
|
||||
if (refCount == 0)
|
||||
{
|
||||
printf("[CoreApplicationWrapperX] Deleting instance\n");
|
||||
delete this;
|
||||
}
|
||||
|
||||
return refCount;
|
||||
}
|
||||
@@ -1,102 +1,240 @@
|
||||
#include "pch.h"
|
||||
#include "FrameworkViewWrapper.h"
|
||||
|
||||
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
HRESULT __stdcall FrameworkViewWrapper::Initialize(ABI::Windows::ApplicationModel::Core::ICoreApplicationView* applicationView)
|
||||
{
|
||||
return m_realView->Initialize(applicationView);
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in Initialize()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
HRESULT hr = m_realView->Initialize(applicationView);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"Initialize failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
wprintf(L"Initialized!!!");
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT __stdcall FrameworkViewWrapper::SetWindow(ABI::Windows::UI::Core::ICoreWindow* window)
|
||||
{
|
||||
// Finally Wraps the coreWindow with xbox CoreWindow
|
||||
window = reinterpret_cast<ICoreWindow*>(new CoreWindowWrapperX((CoreWindow*)window));
|
||||
return m_realView->SetWindow(window);
|
||||
}
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in SetWindow()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
wprintf(L"ERROR: window parameter is null in SetWindow()\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Wrap the CoreWindow with Xbox CoreWindow wrapper
|
||||
ICoreWindow* wrappedWindow = reinterpret_cast<ICoreWindow*>(
|
||||
new (std::nothrow) CoreWindowWrapperX(reinterpret_cast<CoreWindow*>(window)));
|
||||
|
||||
if (!wrappedWindow)
|
||||
{
|
||||
wprintf(L"ERROR: Failed to create CoreWindowWrapperX\n");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Pass to real view (it should AddRef if it needs to keep it)
|
||||
HRESULT hr = m_realView->SetWindow(wrappedWindow);
|
||||
|
||||
// Release our reference
|
||||
wrappedWindow->Release();
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"SetWindow failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
wprintf(L"WindowSet!!!");
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT __stdcall FrameworkViewWrapper::Load(HSTRING entryPoint)
|
||||
{
|
||||
return m_realView->Load(entryPoint);
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in Load()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
HRESULT hr = m_realView->Load(entryPoint);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"Load failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
#include <winrt/Windows.Foundation.h> // Include necessary namespace for Platform::COMException
|
||||
HRESULT __stdcall FrameworkViewWrapper::Run()
|
||||
{
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in Run()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
HRESULT __stdcall FrameworkViewWrapper::Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
wprintf(L"Entering Run()\n");
|
||||
return m_realView->Run();
|
||||
}
|
||||
catch (winrt::hresult_error const& ex) // Replace Platform::COMException with winrt::hresult_error
|
||||
{
|
||||
wprintf(L"COMException caught in Run: HRESULT=0x%08X\n", ex.code());
|
||||
throw; // Re-throw for debugger, or return E_FAIL
|
||||
}
|
||||
try
|
||||
{
|
||||
wprintf(L"Entering Run()\n");
|
||||
|
||||
ComPtr<IFrameworkView> view = m_realView;
|
||||
HRESULT hr = view->Run();
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"Run failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
else
|
||||
{
|
||||
wprintf(L"Run completed successfully\n");
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
wprintf(L"winrt::hresult_error caught in Run: HRESULT=0x%08X, Message=%s\n",
|
||||
ex.code(), ex.message().c_str());
|
||||
return ex.code();
|
||||
}
|
||||
catch (std::exception const& ex)
|
||||
{
|
||||
wprintf(L"std::exception caught in Run: %S\n", ex.what());
|
||||
return E_FAIL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
wprintf(L"Unknown exception caught in Run\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT __stdcall FrameworkViewWrapper::Uninitialize(void)
|
||||
{
|
||||
return m_realView->Uninitialize();
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in Uninitialize()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
HRESULT hr = m_realView->Uninitialize();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
wprintf(L"Uninitialize failed with HRESULT=0x%08X\n", hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT FrameworkViewWrapper::QueryInterface(const IID& riid, void** ppvObject)
|
||||
{
|
||||
LPOLESTR str = nullptr;
|
||||
StringFromIID(riid, &str);
|
||||
wprintf(L"FrameworkViewWrapper [QI] IID Requested: %s\n", str);
|
||||
CoTaskMemFree(str);
|
||||
if (!ppvObject)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (riid == __uuidof(IFrameworkView) ||
|
||||
riid == __uuidof(ICoreApplicationExit) ||
|
||||
riid == __uuidof(IUnknown) ||
|
||||
riid == __uuidof(IInspectable))
|
||||
{
|
||||
*ppvObject = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*/ DEBUG
|
||||
char iidstr[sizeof("{AAAAAAAA-BBBB-CCCC-DDEE-FFGGHHIIJJKK}")];
|
||||
OLECHAR iidwstr[sizeof(iidstr)];
|
||||
StringFromGUID2(riid, iidwstr, ARRAYSIZE(iidwstr));
|
||||
WideCharToMultiByte(CP_UTF8, 0, iidwstr, -1, iidstr, sizeof(iidstr), nullptr, nullptr);
|
||||
MessageBoxA(nullptr, iidstr, typeid(*this).name(), MB_OK);*/
|
||||
}
|
||||
*ppvObject = nullptr;
|
||||
|
||||
return m_realView->QueryInterface(riid, ppvObject);
|
||||
LPOLESTR str = nullptr;
|
||||
if (SUCCEEDED(StringFromIID(riid, &str)))
|
||||
{
|
||||
wprintf(L"FrameworkViewWrapper [QI] IID Requested: %s\n", str);
|
||||
CoTaskMemFree(str);
|
||||
}
|
||||
|
||||
// Check for interfaces we implement directly
|
||||
if (riid == __uuidof(IFrameworkView) ||
|
||||
riid == __uuidof(ICoreApplicationExit) ||
|
||||
riid == __uuidof(IUnknown) ||
|
||||
riid == __uuidof(IInspectable))
|
||||
{
|
||||
*ppvObject = static_cast<IFrameworkView*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Delegate to real view
|
||||
if (m_realView)
|
||||
{
|
||||
return m_realView->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG FrameworkViewWrapper::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_RefCount);
|
||||
ULONG refCount = InterlockedIncrement(&m_RefCount);
|
||||
wprintf(L"FrameworkViewWrapper::AddRef() -> %lu\n", refCount);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
ULONG FrameworkViewWrapper::Release()
|
||||
{
|
||||
ULONG refCount = InterlockedDecrement(&m_RefCount);
|
||||
if (refCount == 0)
|
||||
delete this;
|
||||
return refCount;
|
||||
ULONG refCount = InterlockedDecrement(&m_RefCount);
|
||||
wprintf(L"FrameworkViewWrapper::Release() -> %lu\n", refCount);
|
||||
|
||||
if (refCount == 0)
|
||||
{
|
||||
wprintf(L"FrameworkViewWrapper: Deleting instance\n");
|
||||
delete this;
|
||||
}
|
||||
|
||||
return refCount;
|
||||
}
|
||||
|
||||
HRESULT FrameworkViewWrapper::GetIids(ULONG* iidCount, IID** iids)
|
||||
{
|
||||
return m_realView->GetIids(iidCount, iids);
|
||||
if (!iidCount || !iids)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in GetIids()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realView->GetIids(iidCount, iids);
|
||||
}
|
||||
|
||||
HRESULT FrameworkViewWrapper::GetRuntimeClassName(HSTRING* className)
|
||||
{
|
||||
return m_realView->GetRuntimeClassName(className);
|
||||
if (!className)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in GetRuntimeClassName()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realView->GetRuntimeClassName(className);
|
||||
}
|
||||
|
||||
HRESULT FrameworkViewWrapper::GetTrustLevel(TrustLevel* trustLevel)
|
||||
{
|
||||
return m_realView->GetTrustLevel(trustLevel);
|
||||
if (!trustLevel)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
if (!m_realView)
|
||||
{
|
||||
wprintf(L"ERROR: m_realView is null in GetTrustLevel()\n");
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
return m_realView->GetTrustLevel(trustLevel);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ public:
|
||||
FrameworkViewWrapper(IFrameworkView* windowView)
|
||||
: m_realView(windowView)
|
||||
{
|
||||
|
||||
printf("[Wrapper] FrameworkViewWrapper created!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -69,11 +69,34 @@ inline void UnLoadMods()
|
||||
{
|
||||
FreeLibrary(mod);
|
||||
}
|
||||
|
||||
}
|
||||
#include <winrt/Windows.Services.Store.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> GetProductIdAsync()
|
||||
{
|
||||
auto storeContext = winrt::Windows::Services::Store::StoreContext::GetDefault();
|
||||
auto appLicense = co_await storeContext.GetAppLicenseAsync();
|
||||
winrt::hstring productId = appLicense.SkuStoreId();
|
||||
|
||||
co_return productId;
|
||||
}
|
||||
std::string GetPackageName() {
|
||||
winrt::hstring GamePackage = winrt::Windows::ApplicationModel::Package::Current().Id().FamilyName();
|
||||
std::string packageName = winrt::to_string(GamePackage);
|
||||
|
||||
size_t underscorePos = packageName.find('_');
|
||||
if (underscorePos != std::string::npos) {
|
||||
packageName = packageName.substr(0, underscorePos);
|
||||
}
|
||||
|
||||
return packageName;
|
||||
}
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
winrt::hstring GamePackage = winrt::Windows::ApplicationModel::Package::Current().Id().FamilyName();
|
||||
|
||||
std::string packageName = GetPackageName();
|
||||
InitializeCriticalSection(&XMemSetAllocationHooksLock_X);
|
||||
|
||||
if (DetourIsHelperProcess()) return TRUE;
|
||||
@@ -123,9 +146,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID reserved)
|
||||
{
|
||||
printf("Forza Horizon 2 Presents Fast & Furious");
|
||||
}
|
||||
if (GamePackage == L"HappyDungeons_zyyfzks419954")
|
||||
if (packageName == "HappyDungeons")
|
||||
{
|
||||
printf("Happy Happy Happy Dungeons Dungeons Dungeons\n");
|
||||
}
|
||||
if (packageName == "HappyWars")
|
||||
{
|
||||
printf("Happy Wars Detected!");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -86,6 +86,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "ConnectedStorage.h"
|
||||
#include <shlobj.h>
|
||||
#include <strsafe.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <robuffer.h>
|
||||
#include "../Implementation/Windows.Xbox.Storage.BlobInfoQueryResult.h"
|
||||
#include <winrt/Windows.Storage.FileProperties.h>
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::CreateContainer(winrt::hstring name) const
|
||||
{
|
||||
// LOG_WARNING("[ConnectedStorage] Container %S requested creation\n", name.c_str());
|
||||
|
||||
if (!co_await DoesFolderExist(m_storagePath + L"\\" + name))
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath);
|
||||
co_await folder.CreateFolderAsync(name);
|
||||
}
|
||||
|
||||
//LOG_WARNING("[ConnectedStorage] Container %S created\n", name.c_str());
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::Read(
|
||||
winrt::hstring containerName, winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Storage::Streams::IBuffer> data) const
|
||||
{
|
||||
if (!co_await DoesFolderExist(m_storagePath + L"\\" + containerName)) {
|
||||
co_await CreateContainer(containerName);
|
||||
LOG_INFO("[ConnectedStorage] Container %S created\n", containerName.c_str( ));
|
||||
}
|
||||
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath + L"\\" + containerName);
|
||||
|
||||
for (auto const& pair : data)
|
||||
{
|
||||
auto fileName = pair.Key();
|
||||
//LOG_INFO("FileName -> %ls | folder -> %ls\n", fileName.c_str(), folder.Path().c_str());
|
||||
auto file = co_await folder.GetFileAsync(fileName);
|
||||
auto fileBuffer = co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file);
|
||||
auto bufferByteAccess = fileBuffer.as<Windows::Storage::Streams::IBufferByteAccess>();
|
||||
uint8_t* fileData = nullptr;
|
||||
bufferByteAccess->Buffer(&fileData);
|
||||
auto dataBuffer = pair.Value();
|
||||
auto dataBufferByteAccess = dataBuffer.as<Windows::Storage::Streams::IBufferByteAccess>();
|
||||
uint8_t* dataBufferData = nullptr;
|
||||
dataBufferByteAccess->Buffer(&dataBufferData);
|
||||
memcpy(dataBufferData, fileData, fileBuffer.Length());
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::Upload(
|
||||
winrt::hstring containerName,
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Storage::Streams::IBuffer> blobsToWrite,
|
||||
winrt::Windows::Foundation::Collections::IIterable<winrt::hstring> blobsToDelete,
|
||||
winrt::hstring displayName) const
|
||||
{
|
||||
if (!co_await DoesFolderExist(m_storagePath + L"\\" + containerName)) {
|
||||
co_await CreateContainer(containerName);
|
||||
LOG_INFO("[ConnectedStorage] Container %S created\n", containerName.c_str( ));
|
||||
}
|
||||
|
||||
// if a displayName is provided, inside the folder create a txt called wd_displayname.txt with the displayName
|
||||
if (!displayName.empty( ))
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath + L"\\" + containerName);
|
||||
auto file = co_await folder.CreateFileAsync(L"wd_displayname.txt", winrt::Windows::Storage::CreationCollisionOption::ReplaceExisting);
|
||||
co_await winrt::Windows::Storage::FileIO::WriteTextAsync(file, displayName);
|
||||
}
|
||||
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath + L"\\" + containerName);
|
||||
|
||||
if (blobsToWrite != nullptr)
|
||||
for (auto const& pair : blobsToWrite)
|
||||
{
|
||||
auto fileName = pair.Key();
|
||||
auto dataBuffer = pair.Value();
|
||||
auto file = co_await folder.CreateFileAsync(fileName, winrt::Windows::Storage::CreationCollisionOption::ReplaceExisting);
|
||||
co_await winrt::Windows::Storage::FileIO::WriteBufferAsync(file, dataBuffer);
|
||||
}
|
||||
|
||||
if (blobsToDelete != nullptr)
|
||||
for (auto const& blobName : blobsToDelete)
|
||||
{
|
||||
auto file = co_await folder.GetFileAsync(blobName);
|
||||
co_await file.DeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::
|
||||
Storage::BlobInfo>> WinDurango::impl::ConnectedStorage::GetBlobInfoAsync(winrt::hstring parentContainerName,
|
||||
winrt::hstring blobNamePrefix)
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Xbox::Storage::BlobInfo> blobInfoVector = winrt::single_threaded_vector<winrt::Windows::Xbox::Storage::BlobInfo>( );
|
||||
winrt::hstring s_prefix = blobNamePrefix;
|
||||
|
||||
winrt::hstring storagePath = m_storagePath + L"\\" + parentContainerName;
|
||||
if (!co_await DoesFolderExist(storagePath))
|
||||
co_return blobInfoVector.GetView( );
|
||||
|
||||
auto storageFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(storagePath);
|
||||
auto files = co_await storageFolder.GetFilesAsync( );
|
||||
|
||||
for (auto file : files) {
|
||||
std::wstring_view str_view{ file.Name( ) };
|
||||
if (!str_view._Starts_with(s_prefix))
|
||||
continue;
|
||||
|
||||
winrt::Windows::Storage::FileProperties::BasicProperties folderProperties = co_await file.GetBasicPropertiesAsync( );
|
||||
|
||||
uint32_t size = folderProperties.Size( );
|
||||
|
||||
blobInfoVector.Append({ file.Name( ), size });
|
||||
}
|
||||
co_return blobInfoVector.GetView( );
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::
|
||||
Storage::ContainerInfo2>> WinDurango::impl::ConnectedStorage::GetContainerInfo2Async()
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Xbox::Storage::ContainerInfo2> containerInfoVector = winrt::single_threaded_vector<winrt::Windows::Xbox::Storage::ContainerInfo2>( );
|
||||
|
||||
winrt::hstring storagePath = m_storagePath;
|
||||
auto storageFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(storagePath);
|
||||
auto folders = co_await storageFolder.GetFoldersAsync( );
|
||||
|
||||
for (auto folder : folders) {
|
||||
auto folderProperties = co_await folder.GetBasicPropertiesAsync( );
|
||||
|
||||
uint64_t size = folderProperties.Size( );
|
||||
winrt::Windows::Foundation::DateTime date = folderProperties.DateModified( );
|
||||
|
||||
// check if the folder contains a file called "wd_displayname.txt" and if so, read it
|
||||
winrt::hstring displayName = {};
|
||||
if (co_await DoesFileExist(folder, L"wd_displayname.txt"))
|
||||
{
|
||||
auto file = co_await folder.GetFileAsync(L"wd_displayname.txt");
|
||||
displayName = co_await winrt::Windows::Storage::FileIO::ReadTextAsync(file);
|
||||
}
|
||||
|
||||
if (displayName.empty( ))
|
||||
displayName = folder.DisplayName( );
|
||||
|
||||
containerInfoVector.Append({ folder.Name( ), size, displayName, date, false });
|
||||
}
|
||||
co_return containerInfoVector.GetView( );
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::DeleteContainer(winrt::hstring containerName)
|
||||
{
|
||||
winrt::hstring containerPath = m_storagePath + L"\\" + containerName;
|
||||
if (co_await DoesFolderExist(containerPath)) {
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(containerPath);
|
||||
co_await folder.DeleteAsync( );
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring WinDurango::impl::ConnectedStorage::ObtainPackageName()
|
||||
{
|
||||
return winrt::Windows::ApplicationModel::Package::Current( ).Id( ).FamilyName( );
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> WinDurango::impl::ConnectedStorage::DoesFolderExist(
|
||||
winrt::hstring path)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
co_return false;
|
||||
}
|
||||
|
||||
co_return true;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> WinDurango::impl::ConnectedStorage::DoesFileExist(
|
||||
winrt::Windows::Storage::StorageFolder folder, winrt::hstring path)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await folder.GetFileAsync(path);
|
||||
co_return true;
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
if (ex.code( ) == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
co_return false; // File does not exist
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log unexpected errors for debugging
|
||||
LOG_ERROR("Unexpected error while checking file existence: %ls\n", ex.message( ).c_str( ));
|
||||
throw; // Re-throw unexpected exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::CreateDirectories(const wchar_t* storageType, winrt::hstring& storagePath)
|
||||
{
|
||||
co_await winrt::resume_background( );
|
||||
|
||||
winrt::hstring packageName = ObtainPackageName( );
|
||||
if (packageName.empty( )) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::hstring folderPath = winrt::Windows::Storage::ApplicationData::Current( ).LocalFolder( ).Path( ) + L"\\WinDurango";
|
||||
|
||||
if (!co_await DoesFolderExist(folderPath)) {
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(winrt::Windows::Storage::ApplicationData::Current( ).LocalFolder( ).Path( ));
|
||||
co_await folder.CreateFolderAsync(L"WinDurango");
|
||||
}
|
||||
|
||||
folderPath = folderPath + L"\\" + storageType;
|
||||
|
||||
if (!co_await DoesFolderExist(folderPath))
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(winrt::Windows::Storage::ApplicationData::Current( ).LocalFolder( ).Path( ) + L"\\WinDurango");
|
||||
co_await folder.CreateFolderAsync(storageType);
|
||||
}
|
||||
|
||||
storagePath = folderPath;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::InitializeStorage(const wchar_t* name)
|
||||
{
|
||||
co_await CreateDirectories(name, m_storagePath);
|
||||
|
||||
LOG_INFO("[ConnectedStorage] User storage initialized at %S\n", m_storagePath.c_str());
|
||||
}
|
||||
@@ -0,0 +1,486 @@
|
||||
#include "pch.h"
|
||||
#include "Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
#include <shlobj.h>
|
||||
#include <strsafe.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <robuffer.h>
|
||||
#include "../Implementation/Windows.Xbox.Storage.BlobInfoQueryResult.h"
|
||||
#include <winrt/Windows.Storage.FileProperties.h>
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::CreateContainer(winrt::hstring name) const
|
||||
{
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::hstring containerPath = m_storagePath + L"\\" + name;
|
||||
|
||||
if (!co_await DoesFolderExist(containerPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath);
|
||||
co_await folder.CreateFolderAsync(name, winrt::Windows::Storage::CreationCollisionOption::OpenIfExists);
|
||||
LOG_INFO("[ConnectedStorage] Container %S created\n", name.c_str( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to create container %S: %S\n", name.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::Read(
|
||||
winrt::hstring containerName,
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Storage::Streams::IBuffer> data) const
|
||||
{
|
||||
if (data == nullptr) {
|
||||
LOG_WARNING("[ConnectedStorage] Read called with null data map\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::hstring containerPath = m_storagePath + L"\\" + containerName;
|
||||
|
||||
if (!co_await DoesFolderExist(containerPath)) {
|
||||
co_await CreateContainer(containerName);
|
||||
LOG_INFO("[ConnectedStorage] Container %S created during read\n", containerName.c_str( ));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(containerPath);
|
||||
|
||||
for (auto const& pair : data)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto fileName = pair.Key( );
|
||||
auto dataBuffer = pair.Value( );
|
||||
|
||||
if (dataBuffer == nullptr) {
|
||||
LOG_WARNING("[ConnectedStorage] Null buffer for file %S\n", fileName.c_str( ));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto file = co_await folder.GetFileAsync(fileName);
|
||||
auto fileBuffer = co_await winrt::Windows::Storage::FileIO::ReadBufferAsync(file);
|
||||
|
||||
// Validate buffer capacity
|
||||
if (dataBuffer.Capacity( ) < fileBuffer.Length( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Buffer too small for file %S (need %u, have %u)\n",
|
||||
fileName.c_str( ), fileBuffer.Length( ), dataBuffer.Capacity( ));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get raw buffer pointers
|
||||
auto bufferByteAccess = fileBuffer.as<Windows::Storage::Streams::IBufferByteAccess>( );
|
||||
uint8_t* fileData = nullptr;
|
||||
bufferByteAccess->Buffer(&fileData);
|
||||
|
||||
auto dataBufferByteAccess = dataBuffer.as<Windows::Storage::Streams::IBufferByteAccess>( );
|
||||
uint8_t* dataBufferData = nullptr;
|
||||
dataBufferByteAccess->Buffer(&dataBufferData);
|
||||
|
||||
if (fileData != nullptr && dataBufferData != nullptr) {
|
||||
memcpy(dataBufferData, fileData, fileBuffer.Length( ));
|
||||
dataBuffer.Length(fileBuffer.Length( )); // Set the actual data length
|
||||
LOG_INFO("[ConnectedStorage] Successfully read file %S (%u bytes)\n", fileName.c_str( ), fileBuffer.Length( ));
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("[ConnectedStorage] Failed to get buffer pointers for file %S\n", fileName.c_str( ));
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to read file %S: %S (0x%08X)\n",
|
||||
pair.Key( ).c_str( ), ex.message( ).c_str( ), static_cast<uint32_t>(ex.code( )));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to access container %S: %S\n",
|
||||
containerName.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::Upload(
|
||||
winrt::hstring containerName,
|
||||
winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Windows::Storage::Streams::IBuffer> blobsToWrite,
|
||||
winrt::Windows::Foundation::Collections::IIterable<winrt::hstring> blobsToDelete,
|
||||
winrt::hstring displayName) const
|
||||
{
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::hstring containerPath = m_storagePath + L"\\" + containerName;
|
||||
|
||||
if (!co_await DoesFolderExist(containerPath)) {
|
||||
co_await CreateContainer(containerName);
|
||||
LOG_INFO("[ConnectedStorage] Container %S created during upload\n", containerName.c_str( ));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(containerPath);
|
||||
|
||||
// Write display name if provided
|
||||
if (!displayName.empty( ))
|
||||
{
|
||||
try
|
||||
{
|
||||
auto file = co_await folder.CreateFileAsync(L"wd_displayname.txt",
|
||||
winrt::Windows::Storage::CreationCollisionOption::ReplaceExisting);
|
||||
co_await winrt::Windows::Storage::FileIO::WriteTextAsync(file, displayName);
|
||||
LOG_INFO("[ConnectedStorage] Display name written: %S\n", displayName.c_str( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to write display name: %S\n", ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
|
||||
// Write blobs
|
||||
if (blobsToWrite != nullptr)
|
||||
{
|
||||
for (auto const& pair : blobsToWrite)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto fileName = pair.Key( );
|
||||
auto dataBuffer = pair.Value( );
|
||||
|
||||
if (dataBuffer == nullptr) {
|
||||
LOG_WARNING("[ConnectedStorage] Null buffer for file %S, skipping\n", fileName.c_str( ));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto file = co_await folder.CreateFileAsync(fileName,
|
||||
winrt::Windows::Storage::CreationCollisionOption::ReplaceExisting);
|
||||
co_await winrt::Windows::Storage::FileIO::WriteBufferAsync(file, dataBuffer);
|
||||
LOG_INFO("[ConnectedStorage] Written file %S (%u bytes)\n", fileName.c_str( ), dataBuffer.Length( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to write file %S: %S\n",
|
||||
pair.Key( ).c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete blobs
|
||||
if (blobsToDelete != nullptr)
|
||||
{
|
||||
for (auto const& blobName : blobsToDelete)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto file = co_await folder.GetFileAsync(blobName);
|
||||
co_await file.DeleteAsync( );
|
||||
LOG_INFO("[ConnectedStorage] Deleted file %S\n", blobName.c_str( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
// File might not exist, which is acceptable
|
||||
if (ex.code( ) != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
|
||||
LOG_ERROR("[ConnectedStorage] Failed to delete file %S: %S\n",
|
||||
blobName.c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to access container %S: %S\n",
|
||||
containerName.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::Storage::BlobInfo>>
|
||||
WinDurango::impl::ConnectedStorage::GetBlobInfoAsync(
|
||||
winrt::hstring parentContainerName,
|
||||
winrt::hstring blobNamePrefix)
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Xbox::Storage::BlobInfo> blobInfoVector =
|
||||
winrt::single_threaded_vector<winrt::Windows::Xbox::Storage::BlobInfo>( );
|
||||
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return blobInfoVector.GetView( );
|
||||
}
|
||||
|
||||
winrt::hstring storagePath = m_storagePath + L"\\" + parentContainerName;
|
||||
|
||||
if (!co_await DoesFolderExist(storagePath)) {
|
||||
LOG_INFO("[ConnectedStorage] Container %S does not exist for blob query\n", parentContainerName.c_str( ));
|
||||
co_return blobInfoVector.GetView( );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto storageFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(storagePath);
|
||||
auto files = co_await storageFolder.GetFilesAsync( );
|
||||
|
||||
for (auto file : files)
|
||||
{
|
||||
std::wstring_view fileName{ file.Name( ) };
|
||||
|
||||
// Skip display name metadata file
|
||||
if (fileName == L"wd_displayname.txt") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check prefix match
|
||||
if (!blobNamePrefix.empty( ) && !fileName.starts_with(blobNamePrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto fileProperties = co_await file.GetBasicPropertiesAsync( );
|
||||
uint32_t size = static_cast<uint32_t>(fileProperties.Size( ));
|
||||
blobInfoVector.Append({ file.Name( ), size });
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to get properties for %S: %S\n",
|
||||
file.Name( ).c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to query blobs in container %S: %S\n",
|
||||
parentContainerName.c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
|
||||
co_return blobInfoVector.GetView( );
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::Storage::ContainerInfo2>>
|
||||
WinDurango::impl::ConnectedStorage::GetContainerInfo2Async( )
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Xbox::Storage::ContainerInfo2> containerInfoVector =
|
||||
winrt::single_threaded_vector<winrt::Windows::Xbox::Storage::ContainerInfo2>( );
|
||||
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return containerInfoVector.GetView( );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto storageFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(m_storagePath);
|
||||
auto folders = co_await storageFolder.GetFoldersAsync( );
|
||||
|
||||
for (auto folder : folders)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto folderProperties = co_await folder.GetBasicPropertiesAsync( );
|
||||
uint64_t size = folderProperties.Size( );
|
||||
winrt::Windows::Foundation::DateTime date = folderProperties.DateModified( );
|
||||
|
||||
// Check for custom display name
|
||||
winrt::hstring displayName = {};
|
||||
if (co_await DoesFileExist(folder, L"wd_displayname.txt"))
|
||||
{
|
||||
try
|
||||
{
|
||||
auto file = co_await folder.GetFileAsync(L"wd_displayname.txt");
|
||||
displayName = co_await winrt::Windows::Storage::FileIO::ReadTextAsync(file);
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_WARNING("[ConnectedStorage] Failed to read display name for %S: %S\n",
|
||||
folder.Name( ).c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
|
||||
if (displayName.empty( )) {
|
||||
displayName = folder.DisplayName( );
|
||||
}
|
||||
|
||||
containerInfoVector.Append({ folder.Name( ), size, displayName, date, false });
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to get info for container %S: %S\n",
|
||||
folder.Name( ).c_str( ), ex.message( ).c_str( ));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to query containers: %S\n", ex.message( ).c_str( ));
|
||||
}
|
||||
|
||||
co_return containerInfoVector.GetView( );
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::DeleteContainer(winrt::hstring containerName)
|
||||
{
|
||||
if (m_storagePath.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Storage path not initialized\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::hstring containerPath = m_storagePath + L"\\" + containerName;
|
||||
|
||||
if (co_await DoesFolderExist(containerPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
auto folder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(containerPath);
|
||||
co_await folder.DeleteAsync( );
|
||||
LOG_INFO("[ConnectedStorage] Container %S deleted\n", containerName.c_str( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to delete container %S: %S\n",
|
||||
containerName.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[ConnectedStorage] Container %S does not exist, cannot delete\n", containerName.c_str( ));
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring WinDurango::impl::ConnectedStorage::ObtainPackageName( )
|
||||
{
|
||||
try
|
||||
{
|
||||
return winrt::Windows::ApplicationModel::Package::Current( ).Id( ).FamilyName( );
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to obtain package name: %S\n", ex.message( ).c_str( ));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> WinDurango::impl::ConnectedStorage::DoesFolderExist(winrt::hstring path)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(path);
|
||||
co_return true;
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
if (ex.code( ) == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
||||
ex.code( ) == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND))
|
||||
{
|
||||
co_return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Unexpected error checking folder existence %S: %S\n",
|
||||
path.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> WinDurango::impl::ConnectedStorage::DoesFileExist(
|
||||
winrt::Windows::Storage::StorageFolder folder,
|
||||
winrt::hstring path)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await folder.GetFileAsync(path);
|
||||
co_return true;
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
if (ex.code( ) == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
co_return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Unexpected error checking file existence %S: %S\n",
|
||||
path.c_str( ), ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::CreateDirectories(
|
||||
const wchar_t* storageType,
|
||||
winrt::hstring& storagePath)
|
||||
{
|
||||
// CRITICAL FIX: Removed co_await winrt::resume_background() to prevent threading violations
|
||||
// WinRT async operations are already non-blocking and must stay on correct apartment thread
|
||||
|
||||
winrt::hstring packageName = ObtainPackageName( );
|
||||
if (packageName.empty( )) {
|
||||
LOG_ERROR("[ConnectedStorage] Failed to obtain package name\n");
|
||||
co_return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto localFolder = winrt::Windows::Storage::ApplicationData::Current( ).LocalFolder( );
|
||||
winrt::hstring basePath = localFolder.Path( );
|
||||
winrt::hstring winDurangoPath = basePath + L"\\WinDurango";
|
||||
|
||||
// Create WinDurango folder if needed
|
||||
if (!co_await DoesFolderExist(winDurangoPath))
|
||||
{
|
||||
co_await localFolder.CreateFolderAsync(L"WinDurango",
|
||||
winrt::Windows::Storage::CreationCollisionOption::OpenIfExists);
|
||||
LOG_INFO("[ConnectedStorage] Created WinDurango base folder\n");
|
||||
}
|
||||
|
||||
// Create storage type folder
|
||||
winrt::hstring folderPath = winDurangoPath + L"\\" + storageType;
|
||||
|
||||
if (!co_await DoesFolderExist(folderPath))
|
||||
{
|
||||
auto winDurangoFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(winDurangoPath);
|
||||
co_await winDurangoFolder.CreateFolderAsync(storageType,
|
||||
winrt::Windows::Storage::CreationCollisionOption::OpenIfExists);
|
||||
LOG_INFO("[ConnectedStorage] Created storage type folder: %S\n", storageType);
|
||||
}
|
||||
|
||||
storagePath = folderPath;
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to create directories for %S: %S\n",
|
||||
storageType, ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction WinDurango::impl::ConnectedStorage::InitializeStorage(const wchar_t* name)
|
||||
{
|
||||
try
|
||||
{
|
||||
co_await CreateDirectories(name, m_storagePath);
|
||||
LOG_INFO("[ConnectedStorage] User storage initialized at %S\n", m_storagePath.c_str( ));
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
LOG_ERROR("[ConnectedStorage] Failed to initialize storage: %S\n", ex.message( ).c_str( ));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -100,9 +100,7 @@ namespace Windows
|
||||
interface IGameTransportControls : IInspectable
|
||||
{
|
||||
[propget] HRESULT Title([out][retval] HSTRING* value);
|
||||
[propput] HRESULT Title([in] HSTRING value);
|
||||
[propget] HRESULT Subtitle([out][retval] HSTRING* value);
|
||||
[propput] HRESULT Subtitle([in] HSTRING value);
|
||||
[propget] HRESULT PlaybackStatus([out][retval] Windows.Xbox.Media.GamePlaybackStatus* value);
|
||||
[propput] HRESULT PlaybackStatus([in] Windows.Xbox.Media.GamePlaybackStatus value);
|
||||
[propget] HRESULT SoundLevel([out][retval] Windows.Xbox.Media.SoundLevel* value);
|
||||
|
||||
@@ -4,24 +4,25 @@
|
||||
#include "Windows.Xbox.Input.Gamepad.h"
|
||||
#include "Windows.Xbox.Input.Gamepad.g.cpp"
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.UI.Input.h>
|
||||
#include <windowsx.h>
|
||||
#include <Xinput.h>
|
||||
#include "Windows.Xbox.System.User.h"
|
||||
|
||||
namespace winrt::Windows::Xbox::Input::implementation
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::Input::IGamepad> Gamepad::Gamepads()
|
||||
winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Xbox::Input::IGamepad> Gamepad::Gamepads( )
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepads Queried!\n");
|
||||
|
||||
if (staticGamepads == Foundation::Collections::IVector<winrt::Windows::Xbox::Input::IGamepad>(nullptr) || staticGamepads.Size( ) == 0) {
|
||||
staticGamepads = winrt::single_threaded_vector<Input::IGamepad>( );
|
||||
|
||||
LOG_INFO_W(L"Gamepad || Gamepads Queried!\n");
|
||||
for (DWORD gamepad = 0; gamepad < XUSER_MAX_COUNT; gamepad++)
|
||||
{
|
||||
XINPUT_CAPABILITIES capabilities;
|
||||
if (XInputGetCapabilities(gamepad, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS)
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad %d Created!\n", gamepad);
|
||||
wprintf(L"Gamepad || Gamepad %d Created!\n", gamepad);
|
||||
IGamepad newGamepad = winrt::make<Gamepad>(gamepad);
|
||||
staticGamepads.Append(newGamepad);
|
||||
continue;
|
||||
@@ -30,92 +31,137 @@ namespace winrt::Windows::Xbox::Input::implementation
|
||||
}
|
||||
|
||||
if (staticGamepads.Size( ) == 0) {
|
||||
LOG_INFO_W(L"Gamepad || No Gamepads Found!\n");
|
||||
wprintf(L"Gamepad || No Gamepads Found!\n");
|
||||
IGamepad dummyGamepad = winrt::make<Gamepad>(0);
|
||||
staticGamepads.Append(dummyGamepad);
|
||||
}
|
||||
|
||||
HWND hwnd = GetFocus( );
|
||||
ShowCursor(FALSE);
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
POINT tl = { rc.left, rc.top };
|
||||
POINT br = { rc.right, rc.bottom };
|
||||
MapWindowPoints(hwnd, nullptr, &tl, 1);
|
||||
MapWindowPoints(hwnd, nullptr, &br, 1);
|
||||
RECT screenRect = { tl.x, tl.y, br.x, br.y };
|
||||
ClipCursor(&screenRect);
|
||||
ShowCursor(FALSE);
|
||||
|
||||
return staticGamepads.GetView( );
|
||||
}
|
||||
|
||||
winrt::event_token Gamepad::GamepadAdded(winrt::Windows::Foundation::EventHandler<winrt::Windows::Xbox::Input::GamepadAddedEventArgs> const& handler)
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad Added!\n");
|
||||
LOG_WARNING("Gamepad || GamepadAdded event is not implemented, returning empty token.");
|
||||
LOG_WARNING("Gamepad || GamepadAdded event is not implemented, returning empty token.");
|
||||
return {};
|
||||
}
|
||||
|
||||
void Gamepad::GamepadAdded(winrt::event_token const& token) noexcept
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad Added!\n");
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
|
||||
winrt::event_token Gamepad::GamepadRemoved(winrt::Windows::Foundation::EventHandler<winrt::Windows::Xbox::Input::GamepadRemovedEventArgs> const& handler)
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad Removed!\n");
|
||||
LOG_NOT_IMPLEMENTED(); return {};
|
||||
LOG_INFO_W(L"Gamepad || Gamepad Removed!\n");
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
return {};
|
||||
}
|
||||
|
||||
void Gamepad::GamepadRemoved(winrt::event_token const& token) noexcept
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad Removed!\n");
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
uint64_t Gamepad::Id()
|
||||
|
||||
uint64_t Gamepad::Id( )
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Gamepad ID ( %d ) Queried!\n", m_id);
|
||||
LOG_INFO_W(L"Gamepad || Gamepad ID ( %d ) Queried!\n", m_id);
|
||||
return m_id;
|
||||
}
|
||||
hstring Gamepad::Type()
|
||||
|
||||
hstring Gamepad::Type( )
|
||||
{
|
||||
return L"Windows.Xbox.Input.Gamepad";
|
||||
}
|
||||
winrt::Windows::Xbox::System::User Gamepad::User()
|
||||
|
||||
winrt::Windows::Xbox::System::User Gamepad::User( )
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || User Queried!\n");
|
||||
return System::implementation::User::Users( ).GetAt(Id());
|
||||
LOG_INFO_W(L"Gamepad || User Queried!\n");
|
||||
return System::implementation::User::Users( ).GetAt(Id( ));
|
||||
}
|
||||
winrt::Windows::Xbox::Input::INavigationReading Gamepad::GetNavigationReading()
|
||||
|
||||
winrt::Windows::Xbox::Input::INavigationReading Gamepad::GetNavigationReading( )
|
||||
{
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
winrt::Windows::Xbox::Input::RawNavigationReading Gamepad::GetRawNavigationReading()
|
||||
|
||||
winrt::Windows::Xbox::Input::RawNavigationReading Gamepad::GetRawNavigationReading( )
|
||||
{
|
||||
RawNavigationReading dummyNavigationReading = RawNavigationReading( );
|
||||
dummyNavigationReading.Timestamp = GetTickCount64( );
|
||||
dummyNavigationReading.Buttons |= NavigationButtons::Up;
|
||||
return dummyNavigationReading;
|
||||
dummyNavigationReading.Buttons |= NavigationButtons::Up;
|
||||
return dummyNavigationReading;
|
||||
}
|
||||
|
||||
winrt::event_token Gamepad::NavigationReadingChanged(winrt::Windows::Foundation::TypedEventHandler<winrt::Windows::Xbox::Input::NavigationController, winrt::Windows::Xbox::Input::INavigationReadingChangedEventArgs> const& handler)
|
||||
{
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
|
||||
void Gamepad::NavigationReadingChanged(winrt::event_token const& token) noexcept
|
||||
{
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
|
||||
void Gamepad::SetVibration(winrt::Windows::Xbox::Input::GamepadVibration const& value)
|
||||
{
|
||||
XINPUT_VIBRATION vibration;
|
||||
ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
|
||||
vibration.wLeftMotorSpeed = value.LeftMotorLevel * 65535;
|
||||
vibration.wRightMotorSpeed = value.RightMotorLevel * 65535;
|
||||
vibration.wLeftMotorSpeed = static_cast<WORD>(value.LeftMotorLevel * 65535);
|
||||
vibration.wRightMotorSpeed = static_cast<WORD>(value.RightMotorLevel * 65535);
|
||||
XInputSetState(m_id, &vibration);
|
||||
}
|
||||
winrt::Windows::Xbox::Input::IGamepadReading Gamepad::GetCurrentReading()
|
||||
|
||||
winrt::Windows::Xbox::Input::IGamepadReading Gamepad::GetCurrentReading( )
|
||||
{
|
||||
return winrt::make<implementation::GamepadReading>(GetRawCurrentReading());
|
||||
return winrt::make<implementation::GamepadReading>(GetRawCurrentReading( ));
|
||||
}
|
||||
winrt::Windows::Xbox::Input::RawGamepadReading Gamepad::GetRawCurrentReading()
|
||||
|
||||
winrt::Windows::Xbox::Input::RawGamepadReading Gamepad::GetRawCurrentReading( )
|
||||
{
|
||||
XINPUT_STATE xiState;
|
||||
ZeroMemory(&xiState, sizeof(XINPUT_STATE));
|
||||
RawGamepadReading reading = {};
|
||||
ZeroMemory(&xiState, sizeof(XINPUT_STATE));
|
||||
reading = {};
|
||||
|
||||
if (XInputGetState(m_id, &xiState) == ERROR_SUCCESS)
|
||||
DWORD result = XInputGetState(m_id, &xiState);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
// Debug logging - remove after testing
|
||||
if (xiState.Gamepad.wButtons != 0)
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || Controller %d - Button mask: 0x%04X\n", m_id, xiState.Gamepad.wButtons);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(gamepadButtons); i++)
|
||||
{
|
||||
if (xiState.Gamepad.wButtons & gamepadButtons[ i ].first)
|
||||
{
|
||||
reading.Buttons |= gamepadButtons[ i ].second;
|
||||
|
||||
// Debug: Log when Start button is detected
|
||||
if (gamepadButtons[ i ].first == XINPUT_GAMEPAD_START)
|
||||
{
|
||||
LOG_INFO_W(L"Gamepad || START BUTTON DETECTED!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,27 +172,104 @@ namespace winrt::Windows::Xbox::Input::implementation
|
||||
reading.RightThumbstickX = xiState.Gamepad.sThumbRX / 32768.f;
|
||||
reading.RightThumbstickY = xiState.Gamepad.sThumbRY / 32768.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING_W(L"Gamepad || XInputGetState failed for controller %d with error: %d\n", m_id, result);
|
||||
}
|
||||
|
||||
float lx = 0.0f;
|
||||
float ly = 0.0f;
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(keyboardButtons); i++)
|
||||
{
|
||||
if (GetAsyncKeyState(keyboardButtons[ i ].first))
|
||||
{
|
||||
reading.Buttons |= keyboardButtons[ i ].second;
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState('W') & 0x8000) {
|
||||
ly = 1.0f;
|
||||
}
|
||||
if (GetAsyncKeyState('A') & 0x8000) {
|
||||
lx = -1.0f;
|
||||
}
|
||||
if (GetAsyncKeyState('S') & 0x8000) {
|
||||
ly = -1.0f;
|
||||
}
|
||||
if (GetAsyncKeyState('D') & 0x8000) {
|
||||
lx = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
lx = std::clamp(lx, -1.0f, 1.0f);
|
||||
ly = std::clamp(ly, -1.0f, 1.0f);
|
||||
|
||||
if (lx != 0.0f || ly != 0.0f) {
|
||||
reading.LeftThumbstickX = lx;
|
||||
reading.LeftThumbstickY = ly;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) {
|
||||
reading.RightTrigger = 1.0f;
|
||||
}
|
||||
if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) {
|
||||
reading.LeftTrigger = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mouse Input
|
||||
*/
|
||||
POINT pos;
|
||||
GetCursorPos(&pos);
|
||||
|
||||
if (firstFrame) {
|
||||
prev = pos;
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
int dx = pos.x - prev.x;
|
||||
int dy = pos.y - prev.y;
|
||||
|
||||
deltasumX += dx;
|
||||
deltasumY += dy;
|
||||
prev = pos;
|
||||
|
||||
int centerX = GetSystemMetrics(SM_CXSCREEN) / 2;
|
||||
int centerY = GetSystemMetrics(SM_CYSCREEN) / 2;
|
||||
SetCursorPos(centerX, centerY);
|
||||
prev.x = centerX;
|
||||
prev.y = centerY;
|
||||
|
||||
auto sign = [](float v) { return (v > 0) - (v < 0); };
|
||||
float x = -std::exp((-1.0f / 5.0f) * std::abs(deltasumX)) + 1.0f;
|
||||
float y = -std::exp((-1.0f / 5.0f) * std::abs(deltasumY)) + 1.0f;
|
||||
x *= sign(deltasumX);
|
||||
y *= -sign(deltasumY);
|
||||
|
||||
if (x != 0 || y != 0) {
|
||||
reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f);
|
||||
reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
deltasumX = 0.0f;
|
||||
deltasumY = 0.0f;
|
||||
|
||||
return reading;
|
||||
}
|
||||
|
||||
winrt::event_token Gamepad::ReadingChanged(winrt::Windows::Foundation::TypedEventHandler<winrt::Windows::Xbox::Input::Gamepad, winrt::Windows::Xbox::Input::IGamepadReadingChangedEventArgs> const& handler)
|
||||
{
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
|
||||
void Gamepad::ReadingChanged(winrt::event_token const& token) noexcept
|
||||
{
|
||||
LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented();
|
||||
LOG_NOT_IMPLEMENTED( );
|
||||
throw hresult_not_implemented( );
|
||||
}
|
||||
bool Gamepad::IsTrusted()
|
||||
|
||||
bool Gamepad::IsTrusted( )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
#include "Windows.Xbox.Input.Gamepad.g.h"
|
||||
#include <Xinput.h>
|
||||
#include <windows.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
|
||||
namespace winrt::Windows::Xbox::Input::implementation
|
||||
{
|
||||
|
||||
struct Gamepad : GamepadT<Gamepad>
|
||||
{
|
||||
Gamepad() = default;
|
||||
@@ -29,6 +32,11 @@ namespace winrt::Windows::Xbox::Input::implementation
|
||||
bool IsTrusted();
|
||||
inline static winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Xbox::Input::IGamepad> staticGamepads = { nullptr };
|
||||
uint64_t m_id{ 0 };
|
||||
RawGamepadReading reading = {};
|
||||
POINT prev{ 0, 0 };
|
||||
float deltasumX = 0.0f;
|
||||
float deltasumY = 0.0f;
|
||||
bool firstFrame = true;
|
||||
|
||||
inline static std::pair<WORD, GamepadButtons> const gamepadButtons[] =
|
||||
{
|
||||
@@ -60,10 +68,10 @@ namespace winrt::Windows::Xbox::Input::implementation
|
||||
{ VK_RSHIFT, GamepadButtons::RightThumbstick },
|
||||
{ VK_LCONTROL, GamepadButtons::LeftShoulder },
|
||||
{ VK_RCONTROL, GamepadButtons::RightShoulder },
|
||||
{ 'A', GamepadButtons::A },
|
||||
{ 'B', GamepadButtons::B},
|
||||
{ 'X', GamepadButtons::X },
|
||||
{ 'Y', GamepadButtons::Y},
|
||||
{ VK_SPACE, GamepadButtons::A },
|
||||
{ 'X', GamepadButtons::B},
|
||||
{ 'C', GamepadButtons::X },
|
||||
{ 'V', GamepadButtons::Y},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Windows.Xbox.Storage.BlobInfoQueryResult.h"
|
||||
#include "Windows.Xbox.Storage.BlobInfoQueryResult.g.cpp"
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include "../ConnectedStorage/ConnectedStorage.h"
|
||||
#include "../ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.Storage.FileProperties.h>
|
||||
#include <hstring.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "Windows.Xbox.Storage.ConnectedStorageContainer.h"
|
||||
#include "Windows.Xbox.Storage.ConnectedStorageContainer.g.cpp"
|
||||
#include "../ConnectedStorage/ConnectedStorage.h"
|
||||
#include "../ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
#include "Windows.Xbox.Storage.BlobInfoQueryResult.h"
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
#include "../ConnectedStorage/ConnectedStorage.h"
|
||||
#include "../ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
|
||||
namespace winrt::Windows::Xbox::Storage::implementation
|
||||
{
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
#include "Windows.Xbox.Storage.ContainerInfoQueryResult.h"
|
||||
#include "Windows.Xbox.Storage.ContainerInfoQueryResult.g.cpp"
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include "../ConnectedStorage/ConnectedStorage.h"
|
||||
#include "../ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.Storage.FileProperties.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include "../ConnectedStorage/ConnectedStorage.h"
|
||||
#include "../ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
|
||||
namespace winrt::Windows::Xbox::Storage::implementation
|
||||
{
|
||||
|
||||
@@ -38,11 +38,19 @@ namespace winrt::Windows::Xbox::UI::implementation
|
||||
{
|
||||
co_await resume_background( );
|
||||
|
||||
if (!g_pD3D11XEventFunc && !g_pWDWaitForKeyboardFunc)
|
||||
{
|
||||
g_pD3D11XEventFunc = GetProcAddress(GetModuleHandle(L"d3d11_x.dll"), "WD11XNotify");
|
||||
g_pWDWaitForKeyboardFunc = GetProcAddress(GetModuleHandle(L"d3d11_x.dll"), "WDWaitForKeyboard");
|
||||
}
|
||||
auto hD3D11X = GetModuleHandle(L"d3d11_x.dll");
|
||||
if (!hD3D11X) {
|
||||
OutputDebugString(L"[ERROR] d3d11_x.dll not loaded\n");
|
||||
co_return L"";
|
||||
}
|
||||
|
||||
g_pD3D11XEventFunc = GetProcAddress(hD3D11X, "WD11XNotify_X");
|
||||
g_pWDWaitForKeyboardFunc = GetProcAddress(hD3D11X, "WDWaitForKeyboard");
|
||||
|
||||
if (!g_pD3D11XEventFunc || !g_pWDWaitForKeyboardFunc) {
|
||||
OutputDebugString(L"[ERROR] Could not find WD11XNotify or WDWaitForKeyboard\n");
|
||||
co_return L"";
|
||||
}
|
||||
|
||||
reinterpret_cast<void(__stdcall*)(int)>(g_pD3D11XEventFunc)(1);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "../common/Config.h"
|
||||
#include "ConnectedStorage/ConnectedStorage.h"
|
||||
#include "ConnectedStorage/Windows.Xbox.Storage.ConnectedStorage.h"
|
||||
|
||||
DWORD WINAPI ThreadProc(LPVOID lpParam)
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22621.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
@@ -83,6 +83,7 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(VC_IncludePath);$(ProjectDir);$(WindowsSDK_IncludePath);$(ProjectDir)\External;$(ProjectDir)\$(PlatformShortName)\$(Configuration)\Generated Files;$(ProjectDir)\</IncludePath>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);;D:\Documents\Visual Studio 2022\Projects\WinDurango\dlls\winrt_x\x64\Debug\Generated Files</IncludePath>
|
||||
@@ -132,7 +133,7 @@
|
||||
<MultiProcessorCompilation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</MultiProcessorCompilation>
|
||||
<MultiProcessorCompilation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</MultiProcessorCompilation>
|
||||
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)\imgui;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)\imgui;C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/winrt %(AdditionalOptions)</AdditionalOptions>
|
||||
@@ -163,7 +164,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="ConnectedStorage\ConnectedStorage.h" />
|
||||
<ClInclude Include="ConnectedStorage\Windows.Xbox.Storage.ConnectedStorage.h" />
|
||||
<ClInclude Include="Implementation\Microsoft.Xbox.GameChat.AccessibilitySettingsChangedEventArgs.h" />
|
||||
<ClInclude Include="Implementation\Microsoft.Xbox.GameChat.ChannelUpdatedEventArgs.h" />
|
||||
<ClInclude Include="Implementation\Microsoft.Xbox.GameChat.ChatManager.h" />
|
||||
@@ -553,7 +554,7 @@
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ConnectedStorage\ConnectedStorage.cpp" />
|
||||
<ClCompile Include="ConnectedStorage\Windows.Xbox.Storage.ConnectedStorage.cpp" />
|
||||
<ClCompile Include="Implementation\Microsoft.Xbox.GameChat.AccessibilitySettingsChangedEventArgs.cpp" />
|
||||
<ClCompile Include="Implementation\Microsoft.Xbox.GameChat.ChannelUpdatedEventArgs.cpp" />
|
||||
<ClCompile Include="Implementation\Microsoft.Xbox.GameChat.ChatManager.cpp" />
|
||||
|
||||
Reference in New Issue
Block a user