Everything except for translating file name(s) through the IAppxFile interface into a platform correct/compatible name.
This commit is contained in:
Родитель
bd809cac18
Коммит
545d12bf54
|
@ -16,11 +16,8 @@
|
|||
to non Win32 clients, CreateStreamOnFile is provided to enable easier consumption of the COM APIs.
|
||||
|
||||
0.7 - API changes:
|
||||
* Implemented IAppxFactory's CreatePackageWriter, and CreatePackageReader methods.
|
||||
|
||||
* Implemented IAppxPackageReader's GetPayloadFiles
|
||||
|
||||
* Implemented IAppxFileEnumerator
|
||||
* Implemented IAppxFactory's CreatePackageReader, IAppxPackageReader's GetPayloadFiles, and
|
||||
Implemented IAppxFileEnumerator. Basically, everything used in ExtractContentsSample
|
||||
|
||||
* Moved utf8/utf16 conversion functions into their own header to support marshalling
|
||||
out file Names and content types to clients through the nanoCOM layer.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <codecvt>
|
||||
|
||||
#ifdef WIN32
|
||||
#define UNICODE = 1
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#else
|
||||
// required posix-specific headers
|
||||
|
@ -29,10 +29,13 @@ public:
|
|||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
std::is_convertible<U*,T*>::value || std::is_same<U,T>::value
|
||||
std::is_convertible<U*,T*>::value
|
||||
>::type
|
||||
>
|
||||
ComPtr(U* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
ComPtr(U* ptr) : m_ptr(ptr) { }
|
||||
|
||||
// Distinct from above, this is where ComPtr<T> t = Foo(...) where Foo returns T*
|
||||
ComPtr(T* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
|
||||
// copy ctor
|
||||
ComPtr(const ComPtr& right) : m_ptr(right.m_ptr) { InternalAddRef(); }
|
||||
|
@ -41,20 +44,12 @@ public:
|
|||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
std::is_convertible<U*,T*>::value || std::is_same<U,T>::value
|
||||
std::is_convertible<U*,T*>::value
|
||||
>::type
|
||||
>
|
||||
ComPtr(const ComPtr<U>& right) : m_ptr(right.m_ptr) { InternalAddRef(); }
|
||||
|
||||
// move ctor
|
||||
ComPtr(ComPtr &&right) : m_ptr(nullptr)
|
||||
{
|
||||
if (this != reinterpret_cast<ComPtr*>(&reinterpret_cast<std::int8_t&>(right)))
|
||||
{ Swap(right);
|
||||
}
|
||||
}
|
||||
|
||||
// move ctor that allows instantiation of a class when U* is convertible to T*
|
||||
// move ctor that allows instantiation of a class when U* is convertible to T*
|
||||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
|
@ -75,17 +70,16 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Assignment operator... VERY important.
|
||||
ComPtr& operator=(const ComPtr& right)
|
||||
{
|
||||
if (m_ptr != right.m_ptr) { ComPtr(right).Swap(*this); }
|
||||
ComPtr& operator=(ComPtr &&right)
|
||||
{
|
||||
ComPtr(std::move(right)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assignment operator of T*
|
||||
ComPtr& operator=(T* right)
|
||||
{
|
||||
if (m_ptr != right) { ComPtr(right).Swap(*this); }
|
||||
// Assignment operator...
|
||||
ComPtr& operator=(const ComPtr& right)
|
||||
{
|
||||
if (m_ptr != right.m_ptr) { ComPtr(right).Swap(*this); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -98,13 +92,7 @@ public:
|
|||
>
|
||||
ComPtr& operator=(U* right)
|
||||
{
|
||||
ComPtr(right).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ComPtr& operator=(ComPtr &&right)
|
||||
{
|
||||
ComPtr(std::move(right)).Swap(*this);
|
||||
if (m_ptr != right) { ComPtr(right).Swap(*this); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -112,12 +100,25 @@ public:
|
|||
|
||||
inline T* operator->() const { return m_ptr; }
|
||||
inline T* Get() const { return m_ptr; }
|
||||
|
||||
inline T* Detach()
|
||||
{ T* temp = m_ptr;
|
||||
m_ptr = nullptr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline T** operator&()
|
||||
{ InternalRelease();
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
inline ComPtr<U> As()
|
||||
{
|
||||
ComPtr<U> out;
|
||||
ThrowHrIfFailed(m_ptr->QueryInterface(UuidOfImpl<U>::iid, reinterpret_cast<void**>(&out)));
|
||||
return out;
|
||||
}
|
||||
protected:
|
||||
T* m_ptr = nullptr;
|
||||
|
||||
|
@ -156,7 +157,7 @@ std::wstring utf8_to_utf16(const std::string& utf8string)
|
|||
#ifdef WIN32
|
||||
int mkdirp(std::wstring& utf16Path)
|
||||
{
|
||||
for (int i = 0; i < fullFileName.size(); i++)
|
||||
for (int i = 0; i < utf16Path.size(); i++)
|
||||
{
|
||||
if (utf16Path[i] == L'\0')
|
||||
{
|
||||
|
@ -228,9 +229,7 @@ const FootprintFilesType footprintFilesType[FootprintFilesCount] = {
|
|||
//
|
||||
// Helper function to create a writable IStream over a file with the specified name
|
||||
// under the specified path. This function will also create intermediate
|
||||
// subdirectories if necessary. For simplicity, file names including path are
|
||||
// assumed to be 200 characters or less. A real application should be able to
|
||||
// handle longer names and allocate the necessary buffer dynamically.
|
||||
// subdirectories if necessary.
|
||||
//
|
||||
// Parameters:
|
||||
// path - Path of the folder containing the file to be opened. This should NOT
|
||||
|
@ -254,6 +253,10 @@ HRESULT GetOutputStream(LPCWSTR path, LPCWSTR fileName, IStream** stream)
|
|||
return hr;
|
||||
}
|
||||
|
||||
// Or you can use what-ever allocator/deallocator is best for your platform...
|
||||
LPVOID STDMETHODCALLTYPE MyAllocate(SIZE_T cb) { return std::malloc(cb); }
|
||||
void STDMETHODCALLTYPE MyFree(LPVOID pv) { std::free(pv); }
|
||||
|
||||
//
|
||||
// Creates a cross-plat app package.
|
||||
//
|
||||
|
@ -272,9 +275,12 @@ HRESULT GetPackageReader(LPCWSTR inputFileName, IAppxPackageReader** package)
|
|||
hr = CreateStreamOnFileUTF16(inputFileName, true, &inputStream);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// On Win32 platforms CoCreateAppxFactory defaults to CoTaskMemAlloc/CoTaskMemFree
|
||||
// On non-Win32 platforms CoCreateAppxFactory will return 0x80070032 (e.g. HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED))
|
||||
// So on all platforms, it's always safe to call CoCreateAppxFactoryWithHeap, just be sure to bring your own heap!
|
||||
hr = CoCreateAppxFactoryWithHeap(
|
||||
std::malloc,
|
||||
std::free,
|
||||
MyAllocate,
|
||||
MyFree,
|
||||
APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPAPPXMANIFEST,
|
||||
&appxFactory);
|
||||
|
||||
|
|
|
@ -1,9 +1,33 @@
|
|||
#include "ComHelper.hpp"
|
||||
#pragma once
|
||||
|
||||
#include "AppxPackaging.hpp"
|
||||
#include "UnicodeConversion.hpp"
|
||||
#include "AppxWindows.hpp"
|
||||
#include "ComHelper.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
// internal interface
|
||||
EXTERN_C const IID IID_IxPlatFactory;
|
||||
#ifndef WIN32
|
||||
MIDL_INTERFACE("1f850db4-32b8-4db6-8bf4-5a897eb611f1")
|
||||
interface IxPlatFactory : public IUnknown
|
||||
#else
|
||||
#include "UnKnwn.h"
|
||||
#include "Objidl.h"
|
||||
class IxPlatFactory : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#ifdef WIN32
|
||||
virtual ~IxPlatFactory() {}
|
||||
#endif
|
||||
virtual HRESULT MarshalOutString(std::string& internal, LPWSTR *result) = 0;
|
||||
};
|
||||
|
||||
SpecializeUuidOfImpl(IxPlatFactory);
|
||||
|
||||
namespace xPlat {
|
||||
class AppxFactory : public xPlat::ComClass<AppxFactory, IAppxFactory>
|
||||
class AppxFactory : public ComClass<AppxFactory, IxPlatFactory, IAppxFactory>
|
||||
{
|
||||
public:
|
||||
AppxFactory(APPX_VALIDATION_OPTION validationOptions, COTASKMEMALLOC* memalloc, COTASKMEMFREE* memfree ) :
|
||||
|
@ -13,77 +37,22 @@ namespace xPlat {
|
|||
}
|
||||
|
||||
// IAppxFactory
|
||||
HRESULT STDMETHODCALLTYPE CreatePackageWriter(
|
||||
HRESULT STDMETHODCALLTYPE CreatePackageWriter (
|
||||
IStream* outputStream,
|
||||
APPX_PACKAGE_SETTINGS* ,//settings, TODO: plumb this through
|
||||
IAppxPackageWriter** packageWriter)
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
// return xPlat::ResultOf([&]() {
|
||||
// ThrowErrorIf(Error::InvalidParameter, (packageWriter == nullptr || *packageWriter != nullptr), "Invalid parameter");
|
||||
// ComPtr<IStorageObject> zip(new xPlat::ZipObject(outputStream));
|
||||
// ComPtr<IAppxPackageWriter> result(new AppxPackageObject(m_validationOptions, zip.Get()));
|
||||
// *packageWriter = result.Get();
|
||||
// });
|
||||
}
|
||||
IAppxPackageWriter** packageWriter);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CreatePackageReader(
|
||||
IStream* inputStream,
|
||||
IAppxPackageReader** packageReader)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageReader == nullptr || *packageReader != nullptr), "Invalid parameter");
|
||||
ComPtr<IStorageObject> zip(new xPlat::ZipObject(inputStream));
|
||||
ComPtr<IAppxPackageReader> result(new AppxPackageObject(m_validationOptions, zip.Get()));
|
||||
*packageReader = result.Get();
|
||||
});
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE CreatePackageReader (IStream* inputStream, IAppxPackageReader** packageReader) override;
|
||||
HRESULT STDMETHODCALLTYPE CreateManifestReader(IStream* inputStream, IAppxManifestReader** manifestReader) override ;
|
||||
HRESULT STDMETHODCALLTYPE CreateBlockMapReader (IStream* inputStream, IAppxBlockMapReader** blockMapReader) override;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CreateManifestReader(
|
||||
IStream* inputStream,
|
||||
IAppxManifestReader** manifestReader)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CreateBlockMapReader(
|
||||
IStream* inputStream,
|
||||
IAppxBlockMapReader** blockMapReader)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CreateValidatedBlockMapReader(
|
||||
HRESULT STDMETHODCALLTYPE CreateValidatedBlockMapReader (
|
||||
IStream* blockMapStream,
|
||||
LPCWSTR signatureFileName,
|
||||
IAppxBlockMapReader** blockMapReader)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
IAppxBlockMapReader** blockMapReader) override;
|
||||
|
||||
HRESULT MarshalOutString(std::string& internal, LPWSTR *result)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
ThrowErrorIf(Error::InvalidParameter, (result == nullptr || *result != nullptr), "bad pointer" );
|
||||
auto intermediate = utf8_to_utf16(internal);
|
||||
std::size_t countBytes = sizeof(wchar_t)*(internal.size()+1);
|
||||
*result = reinterpret_cast<LPWSTR>(m_memalloc(countBytes));
|
||||
ThrowErrorIfNot(Error::OutOfMemory, (*result), "Allocation failed!");
|
||||
std::memset(reinterpret_cast<void*>(*result), 0, countBytes);
|
||||
std::memcpy(reinterpret_cast<void*>(*result),
|
||||
reinterpret_cast<void*>(const_cast<wchar_t*>(intermediate.c_str())),
|
||||
countBytes - sizeof(wchar_t));
|
||||
});
|
||||
}
|
||||
// IxPlatFactory
|
||||
HRESULT MarshalOutString(std::string& internal, LPWSTR *result) override;
|
||||
|
||||
COTASKMEMALLOC* m_memalloc;
|
||||
COTASKMEMFREE* m_memfree;
|
||||
|
|
|
@ -19,10 +19,20 @@
|
|||
|
||||
// internal interface
|
||||
EXTERN_C const IID IID_IAppxPackage;
|
||||
#ifndef WIN32
|
||||
MIDL_INTERFACE("51b2c456-aaa9-46d6-8ec9-298220559189")
|
||||
interface IAppxPackage : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IAppxPackage : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#ifdef WIN32
|
||||
virtual ~IAppxPackage() {}
|
||||
#endif
|
||||
|
||||
virtual void Pack(APPX_PACKUNPACK_OPTION options, const std::string& certFile, IStorageObject* from) = 0;
|
||||
virtual void Unpack(APPX_PACKUNPACK_OPTION options, IStorageObject* to) = 0;
|
||||
virtual std::vector<std::string>& GetFootprintFiles() = 0;
|
||||
|
@ -142,7 +152,7 @@ namespace xPlat {
|
|||
{ return ResultOf([&]{
|
||||
ThrowErrorIf(Error::InvalidParameter,(file == nullptr || *file != nullptr), "bad pointer");
|
||||
ThrowErrorIf(Error::Unexpected, (m_cursor >= m_files.size()), "index out of range");
|
||||
*file = ComPtr<IStream>(m_storage->GetFile(m_files[m_cursor])).As<IAppxFile>().Get();
|
||||
*file = ComPtr<IStream>(m_storage->GetFile(m_files[m_cursor])).As<IAppxFile>().Detach();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,15 @@
|
|||
// and what is requiered if the interfaces change.
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __appxpackaging_hpp__
|
||||
#define __appxpackaging_hpp__
|
||||
|
||||
#include "AppxWindows.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <AppxPackaging.h>
|
||||
#else
|
||||
|
||||
#include "AppxWindows.hpp"
|
||||
|
||||
// Interfaces
|
||||
interface IUnknown;
|
||||
interface ISequentialStream;
|
||||
|
@ -1978,8 +1977,8 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE ValidateAppxSignature(char* appx);
|
|||
|
||||
// A call to called CoCreateAppxFactory is required before start using the factory on non-windows platforms specifying
|
||||
// their allocator/de-allocator pair of preference. Failure to do this will result on E_UNEXPECTED.
|
||||
typedef void* STDMETHODCALLTYPE COTASKMEMALLOC(size_t cb);
|
||||
typedef void STDMETHODCALLTYPE COTASKMEMFREE(void* pv);
|
||||
typedef LPVOID STDMETHODCALLTYPE COTASKMEMALLOC(SIZE_T cb);
|
||||
typedef void STDMETHODCALLTYPE COTASKMEMFREE(LPVOID pv);
|
||||
|
||||
// Call specific for Windows. Default to call CoTaskMemAlloc and CoTaskMemFree
|
||||
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#define XPLATAPPX_API extern "C" __declspec(dllexport)
|
||||
|
||||
// UNICODE MUST be defined before you include Windows.h if you want the non-ascii versions of APIs (and you do)
|
||||
#ifdef UNICODE
|
||||
#undef UNICODE
|
||||
#endif
|
||||
|
||||
#define UNICODE
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
@ -47,6 +51,8 @@
|
|||
typedef const WCHAR* LPCWSTR;
|
||||
typedef char BYTE;
|
||||
typedef int BOOL;
|
||||
typedef size_t SIZE_T;
|
||||
typedef void* LPVOID;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
|
|
|
@ -50,10 +50,13 @@ namespace xPlat {
|
|||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
std::is_convertible<U*,T*>::value || std::is_same<U,T>::value
|
||||
std::is_convertible<U*,T*>::value
|
||||
>::type
|
||||
>
|
||||
ComPtr(U* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
ComPtr(U* ptr) : m_ptr(ptr) { }
|
||||
|
||||
// Distinct from above, this is where ComPtr<T> t = Foo(...) where Foo returns T*
|
||||
ComPtr(T* ptr) : m_ptr(ptr) { InternalAddRef(); }
|
||||
|
||||
// copy ctor
|
||||
ComPtr(const ComPtr& right) : m_ptr(right.m_ptr) { InternalAddRef(); }
|
||||
|
@ -62,20 +65,12 @@ namespace xPlat {
|
|||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
std::is_convertible<U*,T*>::value || std::is_same<U,T>::value
|
||||
std::is_convertible<U*,T*>::value
|
||||
>::type
|
||||
>
|
||||
ComPtr(const ComPtr<U>& right) : m_ptr(right.m_ptr) { InternalAddRef(); }
|
||||
|
||||
// move ctor
|
||||
ComPtr(ComPtr &&right) : m_ptr(nullptr)
|
||||
{
|
||||
if (this != reinterpret_cast<ComPtr*>(&reinterpret_cast<std::int8_t&>(right)))
|
||||
{ Swap(right);
|
||||
}
|
||||
}
|
||||
|
||||
// move ctor that allows instantiation of a class when U* is convertible to T*
|
||||
// move ctor that allows instantiation of a class when U* is convertible to T*
|
||||
template<
|
||||
class U,
|
||||
typename = typename std::enable_if<
|
||||
|
@ -96,17 +91,16 @@ namespace xPlat {
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Assignment operator... VERY important.
|
||||
ComPtr& operator=(const ComPtr& right)
|
||||
{
|
||||
if (m_ptr != right.m_ptr) { ComPtr(right).Swap(*this); }
|
||||
ComPtr& operator=(ComPtr &&right)
|
||||
{
|
||||
ComPtr(std::move(right)).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assignment operator of T*
|
||||
ComPtr& operator=(T* right)
|
||||
{
|
||||
if (m_ptr != right) { ComPtr(right).Swap(*this); }
|
||||
// Assignment operator...
|
||||
ComPtr& operator=(const ComPtr& right)
|
||||
{
|
||||
if (m_ptr != right.m_ptr) { ComPtr(right).Swap(*this); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -119,13 +113,7 @@ namespace xPlat {
|
|||
>
|
||||
ComPtr& operator=(U* right)
|
||||
{
|
||||
ComPtr(right).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ComPtr& operator=(ComPtr &&right)
|
||||
{
|
||||
ComPtr(std::move(right)).Swap(*this);
|
||||
if (m_ptr != right) { ComPtr(right).Swap(*this); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -133,6 +121,12 @@ namespace xPlat {
|
|||
|
||||
inline T* operator->() const { return m_ptr; }
|
||||
inline T* Get() const { return m_ptr; }
|
||||
|
||||
inline T* Detach()
|
||||
{ T* temp = m_ptr;
|
||||
m_ptr = nullptr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
inline T** operator&()
|
||||
{ InternalRelease();
|
||||
|
|
|
@ -29,5 +29,5 @@ namespace xPlat {
|
|||
std::map<std::string, ComPtr<IStream>> m_streams;
|
||||
std::string m_root;
|
||||
|
||||
};//class ZipObject
|
||||
};//class DirectoryObject
|
||||
}
|
|
@ -18,13 +18,14 @@ namespace xPlat {
|
|||
//
|
||||
// Win32 error codes
|
||||
//
|
||||
OK = 0,
|
||||
OK = 0x00000000,
|
||||
NotImplemented = 0x80004001,
|
||||
NoInterface = 0x80004002,
|
||||
Unexpected = 0x8000ffff,
|
||||
FileNotFound = 0x80070002,
|
||||
OutOfMemory = 0x8007000E,
|
||||
NotSupported = 0x80070032,
|
||||
InvalidParameter = 0x80070057,
|
||||
NotImplemented = 0x80070078,
|
||||
OutOfMemory = 0x80000002,
|
||||
Unexpected = 0x8000ffff,
|
||||
NoInterface = 0x80000004,
|
||||
|
||||
//
|
||||
// xPlat specific error codes
|
||||
|
@ -50,15 +51,17 @@ namespace xPlat {
|
|||
InflateInitialize = ERROR_FACILITY + 0x0021,
|
||||
InflateRead = ERROR_FACILITY + 0x0022,
|
||||
InflateCorruptData = ERROR_FACILITY + 0x0023,
|
||||
|
||||
// Signature errors
|
||||
AppxSignatureInvalid = ERROR_FACILITY + 0x0030,
|
||||
|
||||
// AppxPackage format errors
|
||||
AppxMissingSignatureP7X = ERROR_FACILITY + 0x0031,
|
||||
AppxMissingContentTypesXML = ERROR_FACILITY + 0x0032,
|
||||
AppxMissingBlockMapXML = ERROR_FACILITY + 0x0033,
|
||||
AppxMissingAppxManifestXML = ERROR_FACILITY + 0x0034,
|
||||
AppxDuplicateFootprintFile = ERROR_FACILITY + 0x0035,
|
||||
|
||||
// Signature errors
|
||||
AppxSignatureInvalid = ERROR_FACILITY + 0x0041,
|
||||
|
||||
};
|
||||
|
||||
// Defines a common exception type to throw in exceptional cases. DO NOT USE FOR FLOW CONTROL!
|
||||
|
|
|
@ -63,8 +63,9 @@ namespace xPlat {
|
|||
|
||||
HRESULT STDMETHODCALLTYPE GetSize(UINT64* size) override
|
||||
{
|
||||
if (size) { *size = m_size; }
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
return ResultOf([&]{
|
||||
if (size) { *size = m_size; }
|
||||
});
|
||||
}
|
||||
|
||||
std::uint64_t Size() { return m_size; }
|
||||
|
|
|
@ -11,10 +11,20 @@
|
|||
|
||||
// internal interface
|
||||
EXTERN_C const IID IID_IStorageObject;
|
||||
#ifndef WIN32
|
||||
MIDL_INTERFACE("ec25b96e-0db1-4483-bdb1-cab1109cb741")
|
||||
interface IStorageObject : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IStorageObject : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
public:
|
||||
#ifdef WIN32
|
||||
virtual ~IStorageObject() {}
|
||||
#endif
|
||||
|
||||
virtual std::string GetPathSeparator() = 0;
|
||||
|
||||
// Obtains a vector of UTF-8 formatted string names contained in the storage object
|
||||
|
|
|
@ -1,39 +1,13 @@
|
|||
#include <memory>
|
||||
#include <iostream>
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
namespace xPlat {
|
||||
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string)
|
||||
{
|
||||
/*
|
||||
from: https://connect.microsoft.com/VisualStudio/feedback/details/1403302/unresolved-external-when-using-codecvt-utf8
|
||||
Posted by Microsoft on 2/16/2016 at 11:49 AM
|
||||
<snip>
|
||||
A workaround is to replace 'char32_t' with 'unsigned int'. In VS2013, char32_t was a typedef of 'unsigned int'.
|
||||
In VS2015, char32_t is a distinct type of it's own. Switching your use of 'char32_t' to 'unsigned int' will get
|
||||
you the old behavior from earlier versions and won't trigger a missing export error.
|
||||
// converts an input utf8 formatted string into a utf16 formatted string
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string);
|
||||
|
||||
There is also a similar error to this one with 'char16_t' that can be worked around using 'unsigned short'.
|
||||
<snip>
|
||||
*/
|
||||
#ifdef WIN32
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<unsigned short>, unsigned short>{}.from_bytes(utf8string.data());
|
||||
#else
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(utf8string.data());
|
||||
#endif
|
||||
std::wstring result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string)
|
||||
{
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(utf16string.data());
|
||||
std::string result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
// converts an input utf16 formatted string into a utf8 formatted string
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string);
|
||||
|
||||
} // namespace xPlat
|
|
@ -3,6 +3,7 @@
|
|||
#include "ComHelper.hpp"
|
||||
#include "StreamBase.hpp"
|
||||
#include "RangeStream.hpp"
|
||||
#include "AppxFactory.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -14,24 +15,25 @@ namespace xPlat {
|
|||
public:
|
||||
// TODO: define what streams to pass in on the .ctor
|
||||
ZipFileStream(
|
||||
std::string name,
|
||||
std::string contentType,
|
||||
IxPlatFactory* factory,
|
||||
bool isCompressed,
|
||||
std::uint32_t offset,
|
||||
std::uint32_t size,
|
||||
IStream* stream
|
||||
) : m_isCompressed(isCompressed), RangeStream(offset, size, stream)
|
||||
) : m_isCompressed(isCompressed), RangeStream(offset, size, stream), m_name(name), m_contentType(contentType), m_factory(factory)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetName(LPWSTR* fileName) override
|
||||
{
|
||||
// TODO: Implement here.
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
return m_factory->MarshalOutString(m_name, fileName);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetContentType(LPWSTR* contentType) override
|
||||
{
|
||||
// TODO: Implement here.
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
return m_factory->MarshalOutString(m_name, contentType);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetCompressionOption(APPX_COMPRESSION_OPTION* compressionOption) override
|
||||
|
@ -43,6 +45,9 @@ namespace xPlat {
|
|||
inline bool IsCompressed() { return m_isCompressed; }
|
||||
|
||||
protected:
|
||||
bool m_isCompressed = false;
|
||||
ComPtr<IxPlatFactory> m_factory;
|
||||
std::string m_name;
|
||||
std::string m_contentType;
|
||||
bool m_isCompressed = false;
|
||||
};
|
||||
}
|
|
@ -4,21 +4,18 @@
|
|||
#include "ComHelper.hpp"
|
||||
#include "StreamBase.hpp"
|
||||
#include "StorageObject.hpp"
|
||||
#include "AppxFactory.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace xPlat {
|
||||
// forward declarations
|
||||
class CentralDirectoryFileHeader;
|
||||
class LocalFileHeader;
|
||||
|
||||
// This represents a raw stream over a.zip file.
|
||||
class ZipObject : public ComClass<ZipObject, IStorageObject>
|
||||
{
|
||||
public:
|
||||
ZipObject(IStream* stream);
|
||||
ZipObject(IxPlatFactory* appxFactory, IStream* stream);
|
||||
|
||||
// StorageObject methods
|
||||
std::string GetPathSeparator() override;
|
||||
|
@ -29,6 +26,7 @@ namespace xPlat {
|
|||
void CommitChanges() override;
|
||||
|
||||
protected:
|
||||
ComPtr<IxPlatFactory> m_factory;
|
||||
ComPtr<IStream> m_stream;
|
||||
std::map<std::string, ComPtr<IStream>> m_streams;
|
||||
};//class ZipObject
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#include "AppxFactory.hpp"
|
||||
#include "UnicodeConversion.hpp"
|
||||
#include "Exceptions.hpp"
|
||||
#include "ZipObject.hpp"
|
||||
#include "AppxPackageObject.hpp"
|
||||
|
||||
namespace xPlat {
|
||||
// IAppxFactory
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreatePackageWriter (
|
||||
IStream* outputStream,
|
||||
APPX_PACKAGE_SETTINGS* ,//settings, TODO: plumb this through
|
||||
IAppxPackageWriter** packageWriter)
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreatePackageReader (
|
||||
IStream* inputStream,
|
||||
IAppxPackageReader** packageReader)
|
||||
{
|
||||
return ResultOf([&]() {
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageReader == nullptr || *packageReader != nullptr), "Invalid parameter");
|
||||
ComPtr<IxPlatFactory> self;
|
||||
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IxPlatFactory>::iid, reinterpret_cast<void**>(&self)));
|
||||
ComPtr<IStorageObject> zip(new ZipObject(self.Get(), inputStream));
|
||||
ComPtr<IAppxPackageReader> result(new AppxPackageObject(m_validationOptions, zip.Get()));
|
||||
*packageReader = result.Detach();
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateManifestReader(
|
||||
IStream* inputStream,
|
||||
IAppxManifestReader** manifestReader)
|
||||
{
|
||||
return ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateBlockMapReader (
|
||||
IStream* inputStream,
|
||||
IAppxBlockMapReader** blockMapReader)
|
||||
{
|
||||
return ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateValidatedBlockMapReader (
|
||||
IStream* blockMapStream,
|
||||
LPCWSTR signatureFileName,
|
||||
IAppxBlockMapReader** blockMapReader)
|
||||
{
|
||||
return ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT AppxFactory::MarshalOutString(std::string& internal, LPWSTR *result)
|
||||
{
|
||||
return ResultOf([&]() {
|
||||
ThrowErrorIf(Error::InvalidParameter, (result == nullptr || *result != nullptr), "bad pointer" );
|
||||
auto intermediate = utf8_to_utf16(internal);
|
||||
std::size_t countBytes = sizeof(wchar_t)*(internal.size()+1);
|
||||
*result = reinterpret_cast<LPWSTR>(m_memalloc(countBytes));
|
||||
ThrowErrorIfNot(Error::OutOfMemory, (*result), "Allocation failed!");
|
||||
std::memset(reinterpret_cast<void*>(*result), 0, countBytes);
|
||||
std::memcpy(reinterpret_cast<void*>(*result),
|
||||
reinterpret_cast<void*>(const_cast<wchar_t*>(intermediate.c_str())),
|
||||
countBytes - sizeof(wchar_t));
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace xPlat
|
|
@ -4,9 +4,11 @@
|
|||
#include "StreamBase.hpp"
|
||||
#include "StorageObject.hpp"
|
||||
#include "AppxPackageObject.hpp"
|
||||
#include "UnicodeConversion.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
@ -20,6 +22,14 @@ namespace xPlat {
|
|||
#define APPXSIGNATURE_P7X "AppxSignature.p7x"
|
||||
#define CONTENT_TYPES_XML "[Content_Types].xml"
|
||||
|
||||
static const std::map<APPX_FOOTPRINT_FILE_TYPE, std::string> footprintFiles =
|
||||
{
|
||||
{APPX_FOOTPRINT_FILE_TYPE_MANIFEST, APPXMANIFEST_XML},
|
||||
{APPX_FOOTPRINT_FILE_TYPE_BLOCKMAP, APPXBLOCKMAP_XML},
|
||||
{APPX_FOOTPRINT_FILE_TYPE_SIGNATURE, APPXSIGNATURE_P7X},
|
||||
{APPX_FOOTPRINT_FILE_TYPE_CODEINTEGRITY, CODEINTEGRITY_CAT},
|
||||
};
|
||||
|
||||
AppxPackageId::AppxPackageId(
|
||||
const std::string& name,
|
||||
const std::string& version,
|
||||
|
@ -169,20 +179,29 @@ namespace xPlat {
|
|||
throw Exception(Error::NotImplemented);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetFootprintFile(APPX_FOOTPRINT_FILE_TYPE type, IAppxFile** file)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
ThrowErrorIf(Error::InvalidParameter, (file == nullptr || *file != nullptr), "bad pointer");
|
||||
auto footprint = footprintFiles.find(type);
|
||||
ThrowErrorIf(Error::FileNotFound, (footprint == footprintFiles.end()), "unknown footprint file type");
|
||||
ComPtr<IStream> stream = GetFile(footprint->second);
|
||||
ThrowErrorIf(Error::FileNotFound, (stream.Get() == nullptr), "requested footprint file not in package")
|
||||
auto result = stream.As<IAppxFile>();
|
||||
*file = result.Detach();
|
||||
});
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetPayloadFile(LPCWSTR fileName, IAppxFile** file)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
// TODO: Implement
|
||||
throw Exception(Error::NotImplemented);
|
||||
ThrowErrorIf(Error::InvalidParameter, (fileName == nullptr || file == nullptr || *file != nullptr), "bad pointer");
|
||||
std::string name = utf16_to_utf8(fileName);
|
||||
ComPtr<IStream> stream = GetFile(name);
|
||||
ThrowErrorIf(Error::FileNotFound, (stream.Get() == nullptr), "requested file not in package")
|
||||
auto result = stream.As<IAppxFile>();
|
||||
*file = result.Detach();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ MIDL_DEFINE_GUID(IID, IID_IAppxPackageEditor,0xE2ADB6DC,0x5E71,0x4416,0x86,0xB6,
|
|||
// internal interfaces.
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxPackage,0x51B2C456,0xAAA9,0x46D6,0x8E,0xC9,0x29,0x82,0x20,0x55,0x91,0x89);
|
||||
MIDL_DEFINE_GUID(IID, IID_IStorageObject,0xEC25B96E,0x0DB1,0x4483,0xBD,0xB1,0xCA,0xB1,0x10,0x9C,0xB7,0x41);
|
||||
|
||||
MIDL_DEFINE_GUID(IID, IID_IxPlatFactory, 0x1f850db4,0x32b8,0x4db6,0x8b,0xf4,0x5a,0x89,0x7e,0xb6,0x11,0xf1);
|
||||
#undef MIDL_DEFINE_GUID
|
||||
|
||||
}
|
||||
|
|
|
@ -71,10 +71,12 @@ set(LIB_PRIVATE_HEADERS
|
|||
|
||||
set(LIB_SOURCES
|
||||
AppxBlockMapObject.cpp
|
||||
AppxFactory.cpp
|
||||
AppxPackageObject.cpp
|
||||
AppxPackaging_i.cpp
|
||||
AppxSignature.cpp
|
||||
InflateStream.cpp
|
||||
InflateStream.cpp
|
||||
UnicodeConversion.cpp
|
||||
xPlatAppx.cpp
|
||||
ZipObject.cpp
|
||||
${DirectoryObject}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include "UnicodeConversion.hpp"
|
||||
|
||||
namespace xPlat {
|
||||
std::wstring utf8_to_utf16(const std::string& utf8string)
|
||||
{
|
||||
/*
|
||||
from: https://connect.microsoft.com/VisualStudio/feedback/details/1403302/unresolved-external-when-using-codecvt-utf8
|
||||
Posted by Microsoft on 2/16/2016 at 11:49 AM
|
||||
<snip>
|
||||
A workaround is to replace 'char32_t' with 'unsigned int'. In VS2013, char32_t was a typedef of 'unsigned int'.
|
||||
In VS2015, char32_t is a distinct type of it's own. Switching your use of 'char32_t' to 'unsigned int' will get
|
||||
you the old behavior from earlier versions and won't trigger a missing export error.
|
||||
|
||||
There is also a similar error to this one with 'char16_t' that can be worked around using 'unsigned short'.
|
||||
<snip>
|
||||
*/
|
||||
#ifdef WIN32
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<unsigned short>, unsigned short>{}.from_bytes(utf8string.data());
|
||||
#else
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(utf8string.data());
|
||||
#endif
|
||||
std::wstring result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string utf16_to_utf8(const std::wstring& utf16string)
|
||||
{
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<wchar_t>>{}.to_bytes(utf16string.data());
|
||||
std::string result(converted.begin(), converted.end());
|
||||
return result;
|
||||
}
|
||||
} // namespace xPlat
|
|
@ -720,6 +720,7 @@ namespace xPlat {
|
|||
|
||||
IStream* ZipObject::GetFile(const std::string& fileName)
|
||||
{
|
||||
// TODO: Make this on-demand populate m_streams and then pull from there.
|
||||
return m_streams[fileName].Get();
|
||||
}
|
||||
|
||||
|
@ -740,7 +741,7 @@ namespace xPlat {
|
|||
|
||||
std::string ZipObject::GetPathSeparator() { return "/"; }
|
||||
|
||||
ZipObject::ZipObject(IStream* stream) : m_stream(stream)
|
||||
ZipObject::ZipObject(IxPlatFactory* appxFactory, IStream* stream) : m_factory(appxFactory), m_stream(stream)
|
||||
{
|
||||
// Confirm that the file IS the correct format
|
||||
EndCentralDirectoryRecord endCentralDirectoryRecord;
|
||||
|
@ -781,6 +782,7 @@ namespace xPlat {
|
|||
// TODO: change to uint64_t when adding full zip64 support
|
||||
std::map<std::uint32_t, std::shared_ptr<LocalFileHeader>> fileRepository;
|
||||
|
||||
// TODO: change population of m_streams into cache semantics and move into ZipObject::GetFile
|
||||
// Read the file repository
|
||||
for (const auto& centralFileHeader : centralDirectory)
|
||||
{
|
||||
|
@ -793,6 +795,9 @@ namespace xPlat {
|
|||
localFileHeader));
|
||||
|
||||
ComPtr<IStream> fileStream (new ZipFileStream(
|
||||
centralFileHeader.second->GetFileName(),
|
||||
"TODO: Implement", // TODO: put value from content type
|
||||
m_factory.Get(),
|
||||
localFileHeader->GetCompressionType() == CompressionType::Deflate,
|
||||
centralFileHeader.second->GetRelativeOffsetOfLocalHeader() + localFileHeader->Size(),
|
||||
localFileHeader->GetCompressedSize(),
|
||||
|
@ -807,4 +812,4 @@ namespace xPlat {
|
|||
m_streams.insert(std::make_pair(centralFileHeader.second->GetFileName(), std::move(fileStream)));
|
||||
}
|
||||
} // ZipObject::ZipObject
|
||||
} // namespace xPlat
|
||||
} // namespace xPlat
|
|
@ -4,6 +4,7 @@
|
|||
#include "RangeStream.hpp"
|
||||
#include "ZipObject.hpp"
|
||||
#include "DirectoryObject.hpp"
|
||||
#include "UnicodeConversion.hpp"
|
||||
#include "ComHelper.hpp"
|
||||
#include "AppxPackaging.hpp"
|
||||
#include "AppxPackageObject.hpp"
|
||||
|
@ -11,6 +12,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Objbase.h>
|
||||
|
@ -129,6 +132,10 @@ static void finalizer(void) { // 3
|
|||
|
||||
#endif
|
||||
|
||||
LPVOID STDMETHODCALLTYPE InternalAllocate(SIZE_T cb) { return std::malloc(cb); }
|
||||
void STDMETHODCALLTYPE InternalFree(LPVOID pv) { std::free(pv); }
|
||||
|
||||
|
||||
XPLATAPPX_API HRESULT STDMETHODCALLTYPE UnpackAppx(
|
||||
APPX_PACKUNPACK_OPTION packUnpackOptions,
|
||||
APPX_VALIDATION_OPTION validationOption,
|
||||
|
@ -144,7 +151,7 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE UnpackAppx(
|
|||
xPlat::ComPtr<IAppxFactory> factory;
|
||||
// We don't need to use the caller's heap here because we're not marshalling any strings
|
||||
// out to the caller. So default to new / delete[] and be done with it!
|
||||
ThrowHrIfFailed(CoCreateAppxFactoryWithHeap(std::malloc, std::free, validationOption, &factory));
|
||||
ThrowHrIfFailed(CoCreateAppxFactoryWithHeap(InternalAllocate, InternalFree, validationOption, &factory));
|
||||
|
||||
xPlat::ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(CreateStreamOnFile(utf8SourcePackage, true, &stream));
|
||||
|
@ -175,7 +182,7 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE PackAppx(
|
|||
ThrowHrIfFailed(CreateStreamOnFile(utf8Destination, false, &stream));
|
||||
|
||||
xPlat::ComPtr<IAppxFactory> factory;
|
||||
ThrowHrIfFailed(CoCreateAppxFactoryWithHeap(std::malloc, std::free, validationOption, &factory));
|
||||
ThrowHrIfFailed(CoCreateAppxFactoryWithHeap(InternalAllocate, InternalFree, validationOption, &factory));
|
||||
|
||||
// TODO: plumb these through
|
||||
APPX_PACKAGE_SETTINGS option {0};
|
||||
|
@ -192,7 +199,16 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE ValidateAppxSignature(char* appx)
|
|||
return xPlat::ResultOf([&]() {
|
||||
xPlat::ComPtr<IStream> rawFile(new xPlat::FileStream(appx, xPlat::FileStream::Mode::READ));
|
||||
{
|
||||
xPlat::ZipObject zip(rawFile.Get());
|
||||
APPX_VALIDATION_OPTION validationOption = APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_FULL;
|
||||
|
||||
std::function<LPVOID STDMETHODCALLTYPE(SIZE_T cb)> allocator=[](SIZE_T cb){return std::malloc(cb);};
|
||||
std::function<void STDMETHODCALLTYPE(LPVOID pv)> deallocator=[](LPVOID pv){ std::free(pv);};
|
||||
|
||||
xPlat::ComPtr<IAppxFactory> factory;
|
||||
ThrowHrIfFailed(CoCreateAppxFactoryWithHeap(InternalAllocate, InternalFree, validationOption, &factory));
|
||||
|
||||
auto internalFactory = factory.As<IxPlatFactory>();
|
||||
xPlat::ZipObject zip(internalFactory.Get(), rawFile.Get());
|
||||
auto p7xStream = zip.GetFile("AppxSignature.p7x");
|
||||
std::vector<std::uint8_t> buffer(sizeof(_BLOBHEADER));
|
||||
|
||||
|
@ -216,8 +232,7 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFile(
|
|||
IStream** stream)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
xPlat::ComPtr<IStream> file(new xPlat::FileStream(utf8File, forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE));
|
||||
*stream = file.Get();
|
||||
*stream = xPlat::ComPtr<IStream>(new xPlat::FileStream(utf8File, forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE)).Detach();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -227,10 +242,9 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFileUTF16(
|
|||
IStream** stream)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
xPlat::ComPtr<IStream> file(new xPlat::FileStream(
|
||||
*stream = xPlat::ComPtr<IStream>(new xPlat::FileStream(
|
||||
xPlat::utf16_to_utf8(utf16File),
|
||||
forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE));
|
||||
*stream = file.Get();
|
||||
forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE)).Detach();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -241,8 +255,7 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactoryWithHeap(
|
|||
IAppxFactory** appxFactory)
|
||||
{
|
||||
return xPlat::ResultOf([&]() {
|
||||
xPlat::ComPtr<IAppxFactory> result(new xPlat::AppxFactory(validationOption, memalloc, memfree));
|
||||
*appxFactory = result.Get();
|
||||
*appxFactory = xPlat::ComPtr<IAppxFactory>(new xPlat::AppxFactory(validationOption, memalloc, memfree)).Detach();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -254,8 +267,6 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
|
|||
#ifdef WIN32
|
||||
return CoCreateAppxFactoryWithHeap(CoTaskMemAlloc, CoTaskMemFree, validationOption, appxFactory);
|
||||
#else
|
||||
return static_cast<HRESULT>(xPlat::Error::NotSupported);
|
||||
// We can't default to CoCreateAppxFactoryWithHeap(new, delete[], validationOption, AppxFactory);
|
||||
// because we can't assume that the client is necessarily using the same heap as us!
|
||||
return static_cast<HRESULT>(Error::NotSupported);
|
||||
#endif
|
||||
}
|
Загрузка…
Ссылка в новой задаче