-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create access module using uwp SharedStorageAccessManager
- Loading branch information
1 parent
e7ece47
commit 6c6d3c9
Showing
9 changed files
with
647 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,6 @@ Thumbs.db | |
*.ilk | ||
*.log | ||
*.dll | ||
*.h | ||
*.jar | ||
[Bb]in | ||
[Dd]ebug*/ | ||
|
268 changes: 268 additions & 0 deletions
268
modules/libaccess_winrt_plugin/libaccess_winrt_plugin.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
#include "pch.h" | ||
#include "libaccess_winrt_plugin.h" | ||
|
||
#include <vlc_access.h> | ||
#include <vlc_input.h> | ||
#include <vlc_charset.h> | ||
|
||
|
||
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<unsigned int> read_async(const DataReader& reader, array_view<uint8_t> 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_sys_t*>(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_sys_t*>(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_sys_t*>(access->p_sys); | ||
|
||
unsigned int total_read; | ||
const auto buffer_view = array_view(static_cast<uint8_t*>(buffer), static_cast<uint32_t>(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<stream_t*>(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<stream_t*>(object); | ||
access_sys_t* p_sys = static_cast<access_sys_t*>(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; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <vlc_common.h> | ||
#include <vlc_plugin.h> | ||
|
||
|
||
static int Open(vlc_object_t*); | ||
static void Close(vlc_object_t*); |
Oops, something went wrong.