From 6c6d3c983bacb69596481a492e386b6336b07fe7 Mon Sep 17 00:00:00 2001 From: Tung Huynh Date: Sun, 5 May 2024 01:03:45 -0700 Subject: [PATCH] create access module using uwp SharedStorageAccessManager --- .gitignore | 1 - .../libaccess_winrt_plugin.cpp | 268 +++++++++++++++++ .../libaccess_winrt_plugin.h | 26 ++ .../libaccess_winrt_plugin.vcxproj | 269 ++++++++++++++++++ .../libaccess_winrt_plugin.vcxproj.filters | 18 ++ modules/libaccess_winrt_plugin/pch.cpp | 1 + modules/libaccess_winrt_plugin/pch.h | 14 + modules/libaccess_winrt_plugin/targetver.h | 8 + modules/modules.sln | 43 +++ 9 files changed, 647 insertions(+), 1 deletion(-) create mode 100644 modules/libaccess_winrt_plugin/libaccess_winrt_plugin.cpp create mode 100644 modules/libaccess_winrt_plugin/libaccess_winrt_plugin.h create mode 100644 modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj create mode 100644 modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj.filters create mode 100644 modules/libaccess_winrt_plugin/pch.cpp create mode 100644 modules/libaccess_winrt_plugin/pch.h create mode 100644 modules/libaccess_winrt_plugin/targetver.h create mode 100644 modules/modules.sln diff --git a/.gitignore b/.gitignore index 7ff34fb..2c69591 100755 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ Thumbs.db *.ilk *.log *.dll -*.h *.jar [Bb]in [Dd]ebug*/ diff --git a/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.cpp b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.cpp new file mode 100644 index 0000000..e34aca5 --- /dev/null +++ b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.cpp @@ -0,0 +1,268 @@ +#include "pch.h" +#include "libaccess_winrt_plugin.h" + +#include +#include +#include + + +using namespace winrt; +using namespace Windows::Storage; +using namespace Windows::Storage::Streams; +using namespace Windows::ApplicationModel::DataTransfer; +using namespace Windows::Foundation; + + +/***************************************************************************** +* Module descriptor +*****************************************************************************/ + +vlc_module_begin() +set_shortname(N_("WinRTInput")) +set_description(N_("WinRT input")) +set_category(CAT_INPUT) +set_subcategory(SUBCAT_INPUT_ACCESS) +set_capability("access", 80) +add_shortcut("winrt", "file") +set_callbacks(&Open, &Close) +vlc_module_end() + + +struct access_sys_t +{ + IRandomAccessStream read_stream; + DataReader data_reader; + uint64_t i_pos; + bool b_eof; +}; + +namespace +{ + bool is_token_valid(const hstring& future_access_token) { + // TODO: validate token + // auto charBegin = future_access_token[0]; + // auto charEnd = future_access_token[future_access_token.size() - 1]; + // return !((charBegin != '{') || ((charEnd != '}') || future_access_token->Length() < 32)); + return true; + } + + /***************************************************************************** + * Local prototypes + *****************************************************************************/ + + /** + * Handles the file opening + */ + IAsyncAction open_file_from_path_async(access_sys_t* p_sys, const hstring& path) + { + auto file = co_await StorageFile::GetFileFromPathAsync(path); + auto stream = co_await file.OpenReadAsync(); + p_sys->read_stream = stream; + p_sys->data_reader = DataReader(stream); + } + + int open_file_from_path(access_sys_t* p_sys, const hstring& path) + { + try + { + open_file_from_path_async(p_sys, path).get(); + return VLC_SUCCESS; + } + catch (hresult_error const& ex) + { + OutputDebugString(ex.message().c_str()); + OutputDebugString(L"Failed to open file."); + return VLC_EGENERIC; + } + } + + IAsyncAction open_file_from_token_async(access_sys_t* p_sys, const hstring& token) + { + auto file = co_await SharedStorageAccessManager::RedeemTokenForFileAsync(token); + auto stream = co_await file.OpenReadAsync(); + p_sys->read_stream = stream; + p_sys->data_reader = DataReader(stream); + } + + int open_file_from_token(access_sys_t* p_sys, const hstring& token) + { + try + { + open_file_from_token_async(p_sys, token).get(); + return VLC_SUCCESS; + } + catch (hresult_error const& ex) + { + OutputDebugString(ex.message().c_str()); + OutputDebugString(L"Failed to open file."); + return VLC_EGENERIC; + } + } + + IAsyncOperation read_async(const DataReader& reader, array_view buffer) + { + const auto bytes_loaded = co_await reader.LoadAsync(buffer.size()); + buffer = array_view(buffer.data(), bytes_loaded); + reader.ReadBytes(buffer); + co_return bytes_loaded; + } + + /* */ + int seek(stream_t* access, uint64_t position) + { + access_sys_t* p_sys = static_cast(access->p_sys); + + try + { + p_sys->read_stream.Seek(position); + p_sys->i_pos = position; + p_sys->b_eof = p_sys->read_stream.Position() >= p_sys->read_stream.Size(); + } + catch (hresult_error const& ex) + { + OutputDebugString(ex.message().c_str()); + return VLC_EGENERIC; + } + + return VLC_SUCCESS; + } + + /* */ + int control(stream_t* access, int query, va_list args) + { + const auto p_sys = static_cast(access->p_sys); + + VLC_UNUSED(access); + switch (query) + { + case STREAM_CAN_FASTSEEK: + case STREAM_CAN_PAUSE: + case STREAM_CAN_SEEK: + case STREAM_CAN_CONTROL_PACE: { + bool* b = va_arg(args, bool*); + *b = true; + return VLC_SUCCESS; + } + + case STREAM_GET_PTS_DELAY: { + int64_t* d = va_arg(args, int64_t*); + *d = DEFAULT_PTS_DELAY; + return VLC_SUCCESS; + } + + case STREAM_SET_PAUSE_STATE: + return VLC_SUCCESS; + + case STREAM_GET_SIZE: { + *va_arg(args, uint64_t*) = p_sys->read_stream.Size(); + return VLC_SUCCESS; + } + default: + return VLC_EGENERIC; + } + } + + /* */ + ssize_t read(stream_t* access, void* buffer, size_t size) + { + if (buffer == nullptr) + { + if (seek(access, size) == VLC_SUCCESS) + return size; + return 0; + } + + access_sys_t* p_sys = static_cast(access->p_sys); + + unsigned int total_read; + const auto buffer_view = array_view(static_cast(buffer), static_cast(size)); + + try + { + total_read = read_async(p_sys->data_reader, buffer_view).get(); /* block with wait since we're in a worker thread */ + } + catch (hresult_error const& ex) + { + OutputDebugString(L"Failure while reading block\n"); + if (ex.code() == HRESULT_FROM_WIN32(ERROR_OPLOCK_HANDLE_CLOSED)) { + if (open_file_from_path(p_sys, to_hstring(access->psz_location)) == VLC_SUCCESS) { + p_sys->read_stream.Seek(p_sys->i_pos); + return read(access, buffer, size); + } + OutputDebugString(L"Failed to reopen file\n"); + } + return 0; + } + + p_sys->i_pos += total_read; + p_sys->b_eof = p_sys->read_stream.Position() >= p_sys->read_stream.Size(); + if (p_sys->b_eof) { + OutputDebugString(L"End of file reached\n"); + } + + return total_read; + } +} + +int Open(vlc_object_t* object) +{ + stream_t* access = reinterpret_cast(object); + hstring access_token; + int (*pf_open)(access_sys_t*, const hstring&); + + if (strncmp(access->psz_name, "winrt", 5) == 0) { + access_token = to_hstring(access->psz_location); + if (!is_token_valid(access_token)) + return VLC_EGENERIC; + pf_open = open_file_from_token; + } + else if (strncmp(access->psz_name, "file", 4) == 0) { + char* pos = strstr(access->psz_filepath, "winrt:\\\\"); + if (pos && strlen(pos) > 8) { + access_token = to_hstring(pos + 8); + if (!is_token_valid(access_token)) + return VLC_EGENERIC; + pf_open = open_file_from_token; + } + else + { + pf_open = open_file_from_path; + access_token = to_hstring(access->psz_filepath); + } + } + else + return VLC_EGENERIC; + + const auto p_sys = new(std::nothrow) access_sys_t{nullptr, nullptr, 0, false}; + access->p_sys = p_sys; + if (p_sys == nullptr) + return VLC_EGENERIC; + + p_sys->i_pos = 0; + if (pf_open(p_sys, access_token) != VLC_SUCCESS) { + OutputDebugStringW(L"Error opening file with Path"); + Close(object); + return VLC_EGENERIC; + } + + access->pf_read = &read; + access->pf_seek = &seek; + access->pf_control = &control; + + return VLC_SUCCESS; +} + +/* */ +void Close(vlc_object_t* object) +{ + stream_t* access = reinterpret_cast(object); + access_sys_t* p_sys = static_cast(access->p_sys); + if (p_sys->data_reader != nullptr) { + p_sys->data_reader = nullptr; + } + if (p_sys->read_stream != nullptr) { + p_sys->read_stream = nullptr; + } + delete p_sys; +} + diff --git a/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.h b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.h new file mode 100644 index 0000000..0f97ef2 --- /dev/null +++ b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.h @@ -0,0 +1,26 @@ +#pragma once + +#ifndef MODULE_STRING +#define MODULE_STRING "access_winrt" +#endif + +#ifdef _MSC_VER /* help visual studio compile vlc headers */ +# define inline __inline +# define strdup _strdup +# define strcasecmp _stricmp +# define ssize_t SSIZE_T +# define N_(x) x +# define _(x) x +int poll(struct pollfd*, unsigned, int); +# define restrict __restrict +#endif + +# define VLC_MODULE_COPYRIGHT "Copyright"; +# define VLC_MODULE_LICENSE VLC_LICENSE_LGPL_2_1_PLUS; + +#include +#include + + +static int Open(vlc_object_t*); +static void Close(vlc_object_t*); diff --git a/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj new file mode 100644 index 0000000..babeca5 --- /dev/null +++ b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj @@ -0,0 +1,269 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {fa53fdfb-f96c-48bd-8596-f09ac5e4caa4} + DynamicLibrary + libaccess_winrt_plugin + en-US + 14.0 + true + Windows Store + 10.0.22621.0 + 10.0.18362.0 + 10.0 + + + + DynamicLibrary + true + v143 + + + DynamicLibrary + true + v143 + + + DynamicLibrary + true + v143 + + + DynamicLibrary + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + false + false + + + false + false + + + false + false + C:\Users\tung7\source\repos\libvlc-nuget\vlc\include;$(ExternalIncludePath) + + + false + false + + + + Use + false + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + Use + false + stdcpp20 + Default + + + Console + false + false + + + + + Use + false + + + Console + false + false + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj.filters b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj.filters new file mode 100644 index 0000000..87bfe4d --- /dev/null +++ b/modules/libaccess_winrt_plugin/libaccess_winrt_plugin.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/libaccess_winrt_plugin/pch.cpp b/modules/libaccess_winrt_plugin/pch.cpp new file mode 100644 index 0000000..bcb5590 --- /dev/null +++ b/modules/libaccess_winrt_plugin/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/modules/libaccess_winrt_plugin/pch.h b/modules/libaccess_winrt_plugin/pch.h new file mode 100644 index 0000000..2c252f9 --- /dev/null +++ b/modules/libaccess_winrt_plugin/pch.h @@ -0,0 +1,14 @@ +#pragma once + +#include "targetver.h" + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include +#include +#include +#include +#include diff --git a/modules/libaccess_winrt_plugin/targetver.h b/modules/libaccess_winrt_plugin/targetver.h new file mode 100644 index 0000000..a66ecb0 --- /dev/null +++ b/modules/libaccess_winrt_plugin/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/modules/modules.sln b/modules/modules.sln new file mode 100644 index 0000000..805da29 --- /dev/null +++ b/modules/modules.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34622.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libaccess_winrt_plugin", "libaccess_winrt_plugin\libaccess_winrt_plugin.vcxproj", "{FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|ARM.ActiveCfg = Debug|ARM + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|ARM.Build.0 = Debug|ARM + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|ARM64.Build.0 = Debug|ARM64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|x64.ActiveCfg = Debug|x64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|x64.Build.0 = Debug|x64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|x86.ActiveCfg = Debug|Win32 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Debug|x86.Build.0 = Debug|Win32 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|ARM.ActiveCfg = Release|ARM + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|ARM.Build.0 = Release|ARM + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|ARM64.ActiveCfg = Release|ARM64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|ARM64.Build.0 = Release|ARM64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|x64.ActiveCfg = Release|x64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|x64.Build.0 = Release|x64 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|x86.ActiveCfg = Release|Win32 + {FA53FDFB-F96C-48BD-8596-F09AC5E4CAA4}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {676900B8-3FB6-43EA-A04D-E74D3A62FE00} + EndGlobalSection +EndGlobal