mirror of
https://github.com/WinDurango/WinDurango.git
synced 2026-01-31 00:55:17 +01:00
227 lines
9.2 KiB
C++
227 lines
9.2 KiB
C++
#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
|
|
{
|
|
// printf("[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);
|
|
}
|
|
|
|
//printf("[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);
|
|
printf("[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();
|
|
//printf("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);
|
|
printf("[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);
|
|
}
|
|
catch (...)
|
|
{
|
|
co_return false;
|
|
}
|
|
|
|
co_return true;
|
|
}
|
|
|
|
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);
|
|
|
|
printf("[ConnectedStorage] User storage initialized at %S\n", m_storagePath.c_str());
|
|
}
|