diff options
author | crupest <crupest@outlook.com> | 2022-02-03 17:55:00 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-02-03 17:55:00 +0800 |
commit | 5aca7b099c46a87a859f40110efce708200a4bc8 (patch) | |
tree | 76a0daef247ab2b2269eebdbbda10134f213d1ca /src/common/platform/win/StreamConvert.cpp | |
parent | d15172cfe1ac8558567c1b1c10c2e671b0d1f033 (diff) | |
download | cru-5aca7b099c46a87a859f40110efce708200a4bc8.tar.gz cru-5aca7b099c46a87a859f40110efce708200a4bc8.tar.bz2 cru-5aca7b099c46a87a859f40110efce708200a4bc8.zip |
...
Diffstat (limited to 'src/common/platform/win/StreamConvert.cpp')
-rw-r--r-- | src/common/platform/win/StreamConvert.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/common/platform/win/StreamConvert.cpp b/src/common/platform/win/StreamConvert.cpp new file mode 100644 index 00000000..1d077573 --- /dev/null +++ b/src/common/platform/win/StreamConvert.cpp @@ -0,0 +1,53 @@ +#include "cru/common/platform/win/StreamConvert.hpp" +#include "BrigdeComStream.hpp" +#include "cru/common/Exception.hpp" +#include "cru/common/io/MemoryStream.hpp" +#include "cru/common/io/OpenFileFlag.hpp" +#include "cru/common/platform/win/ComAutoInit.hpp" +#include "cru/common/platform/win/Exception.hpp" +#include "cru/common/platform/win/Win32FileStream.hpp" + +#include <shlwapi.h> +#include <winnt.h> + +namespace cru::platform::win { +IStream* ConvertStreamToComStream(io::Stream* stream) { + static ComAutoInit com_auto_init; + + if (auto memory_stream = dynamic_cast<io::MemoryStream*>(stream)) { + return SHCreateMemStream( + reinterpret_cast<const BYTE*>(memory_stream->GetBuffer()), + memory_stream->GetSize()); + } else if (auto file_stream = dynamic_cast<Win32FileStream*>(stream)) { + auto path = file_stream->GetPath(); + auto flags = file_stream->GetOpenFileFlags(); + DWORD grfMode = STGM_SHARE_DENY_NONE | STGM_FAILIFTHERE; + if (flags & io::OpenFileFlags::Read) { + if (flags & io::OpenFileFlags::Write) { + grfMode |= STGM_READWRITE; + } else { + grfMode |= STGM_READ; + } + } else { + if (flags & io::OpenFileFlags::Write) { + grfMode |= STGM_WRITE; + } else { + throw Exception(u"Stream must be readable or writable."); + } + } + + IStream* result; + + ThrowIfFailed(SHCreateStreamOnFileEx( + path.WinCStr(), grfMode, FILE_ATTRIBUTE_NORMAL, FALSE, NULL, &result)); + + LARGE_INTEGER position; + position.QuadPart = stream->Tell(); + result->Seek(position, STREAM_SEEK_SET, NULL); + + return result; + } else { + return new BridgeComStream(stream); + } +} +} // namespace cru::platform::win |