Merged PR 2308191: [MSIX SDK] add a c-make switch to exclude bundles from unpack
Enable the user to disable bundle support for the SDK by specifying -DSKIP_BUNDLES=on on CMake. If the user tries to unpack a bundle or create a bundle factory they will get 0x80070032 (E_NOTSUPPORTED). The binary size decreases ~60k. Win x64 - bundle: 464 k - no bundle: 413 k Win x86 - bundle: 330 k - no bundle: 293 k Linux - bundle: 5,424 k - no bundle: 5,330 k AOSP arm - bundle: 4,381 k - no bundle: 4,313 k AOSP arm v7a - bundle: 4,288 k - no bundle: 4,220 k MacOS - bundle: 4,487 k - no bundle: 4,413 k iOS arm64 - bundle: 4,516 k - no bundle: 4,458 k Related work items: #18753331
This commit is contained in:
Родитель
f895380e77
Коммит
dea2e72be9
|
@ -18,6 +18,7 @@ option(LINUX "Build for Linux" OFF)
|
|||
option(USE_VALIDATION_PARSER "Turn on to validates using the resouce schemas. Default (OFF) validates XML files are just valid XML" OFF)
|
||||
option(USE_SHARED_ZLIB "Choose the type of dependency for zlib, Use the -DUSE_SHARED_ZLIB=on to have a shared dependency. Default is 'off' (static)" OFF)
|
||||
option(USE_STATIC_MSVC "Windows only. Pass /MT as a compiler flag to use the staic version of the run-time library. Default is 'off' (dynamic)" OFF)
|
||||
option(SKIP_BUNDLES "Removes bundle functionality from the MSIX SDK. Default is 'off'" OFF)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel. Use the -DCMAKE_BUILD_TYPE=[option] to specify.")
|
||||
set(XML_PARSER "" CACHE STRING "Choose the type of parser, options are: [xerces, msxml6]. Use the -DXML_PARSER=[option] to specify.")
|
||||
|
|
11
makeaosp.sh
11
makeaosp.sh
|
@ -8,6 +8,7 @@ version=19
|
|||
sdk=
|
||||
sdkver=24
|
||||
dataCompressionLib=NDK_libz
|
||||
bundle=off
|
||||
|
||||
usage()
|
||||
{
|
||||
|
@ -19,6 +20,7 @@ usage()
|
|||
echo $'\t' "-arch Architecture ABI. Default x86"
|
||||
echo $'\t' "-b Build type. Default MinSizeRel"
|
||||
echo $'\t' "-xzlib Use MSIX SDK Zlib instead of inbox libz.so"
|
||||
echo $'\t' "-sb Skip bundle support."
|
||||
}
|
||||
|
||||
printsetup()
|
||||
|
@ -30,6 +32,7 @@ printsetup()
|
|||
echo "Architecture:" $arch
|
||||
echo "Build Type:" $build
|
||||
echo "Zlib:" $dataCompressionLib
|
||||
echo "Skip bundle support:" $bundle
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
|
@ -58,8 +61,10 @@ while [ "$1" != "" ]; do
|
|||
-sdkver ) shift
|
||||
sdkver=$1
|
||||
;;
|
||||
* ) usage
|
||||
exit 1
|
||||
-sb ) bundle="on"
|
||||
;;
|
||||
* ) usage
|
||||
exit 1
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
@ -96,5 +101,5 @@ cmake -DCMAKE_SYSTEM_NAME=Android \
|
|||
-DCMAKE_ANDROID_ARCH_ABI="$arch" \
|
||||
-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
|
||||
-DCMAKE_ANDROID_STL_TYPE=c++_shared \
|
||||
-DCMAKE_BUILD_TYPE="$build" $zlib -DAOSP=on ..
|
||||
-DCMAKE_BUILD_TYPE="$build" $zlib -DSKIP_BUNDLES=$bundle -DAOSP=on ..
|
||||
make
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
build=MinSizeRel
|
||||
arch=x86_64
|
||||
dataCompressionLib=libcompression
|
||||
bundle=off
|
||||
|
||||
usage()
|
||||
{
|
||||
|
@ -10,6 +11,7 @@ usage()
|
|||
echo $'\t' "-b Build type. Default MinSizeRel"
|
||||
echo $'\t' "-arch OSX Architecture. Default x86_64 (simulator)"
|
||||
echo $'\t' "-xzlib Use MSIX SDK Zlib instead of inbox libCompression api. Default on iOS is libCompression."
|
||||
echo $'\t' "-sb Skip bundle support."
|
||||
}
|
||||
|
||||
printsetup()
|
||||
|
@ -17,6 +19,7 @@ printsetup()
|
|||
echo "Build Type:" $build
|
||||
echo "Architecture:" $arch
|
||||
echo "Data Compression library:" $dataCompressionLib
|
||||
echo "Skip bundle support:" $bundle
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
|
@ -30,6 +33,8 @@ while [ "$1" != "" ]; do
|
|||
-xzlib )dataCompressionLib=MSIX_SDK_zlib
|
||||
zlib="-DUSE_MSIX_SDK_ZLIB=on"
|
||||
;;
|
||||
-sb ) bundle="on"
|
||||
;;
|
||||
-h ) usage
|
||||
exit
|
||||
;;
|
||||
|
@ -46,5 +51,5 @@ cd .vs
|
|||
# clean up any old builds of msix modules
|
||||
find . -name *msix* -d | xargs rm -r
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$build $zlib -DIOS=on -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.cmake -DCMAKE_OSX_ARCHITECTURES=$arch ..
|
||||
cmake -DCMAKE_BUILD_TYPE=$build $zlib -DIOS=on -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.cmake -DCMAKE_OSX_ARCHITECTURES=$arch -DSKIP_BUNDLES=$bundle ..
|
||||
make
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
#!/bin/bash
|
||||
# script to build on linux
|
||||
build=MinSizeRel
|
||||
bundle=off
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "usage: makelinux [-b buildType]"
|
||||
echo "usage: makelinux [-b buildType] [-sb]"
|
||||
echo $'\t' "-b Build type. Default MinSizeRel"
|
||||
echo $'\t' "-sb Skip bundle support."
|
||||
}
|
||||
|
||||
printsetup()
|
||||
{
|
||||
echo "Build Type:" $build
|
||||
echo "Skip bundle support:" $bundle
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
|
@ -21,6 +24,8 @@ while [ "$1" != "" ]; do
|
|||
-h ) usage
|
||||
exit
|
||||
;;
|
||||
-sb ) bundle="on"
|
||||
;;
|
||||
* ) usage
|
||||
exit 1
|
||||
esac
|
||||
|
@ -34,5 +39,5 @@ cd .vs
|
|||
# clean up any old builds of msix modules
|
||||
find . -name *msix* -d | xargs rm -r
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$build -DLINUX=on ..
|
||||
cmake -DCMAKE_BUILD_TYPE=$build -DSKIP_BUNDLES=$bundle -DLINUX=on ..
|
||||
make
|
||||
|
|
|
@ -2,18 +2,21 @@
|
|||
# script to build on mac
|
||||
build=MinSizeRel
|
||||
dataCompressionLib=libcompression
|
||||
bundle=off
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "usage: makemac [-b buildType] [-xzlib]"
|
||||
echo $'\t' "-b Build type. Default MinSizeRel"
|
||||
echo $'\t' "-xzlib Use MSIX SDK Zlib instead of inbox libCompression api. Default on MacOS is libCompression."
|
||||
echo $'\t' "-sb Skip bundle support."
|
||||
}
|
||||
|
||||
printsetup()
|
||||
{
|
||||
echo "Build Type:" $build
|
||||
echo "Data Compression library:" $dataCompressionLib
|
||||
echo "Skip bundle support:" $bundle
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
|
@ -24,6 +27,8 @@ while [ "$1" != "" ]; do
|
|||
-xzlib )dataCompressionLib=MSIX_SDK_zlib
|
||||
zlib="-DUSE_MSIX_SDK_ZLIB=on"
|
||||
;;
|
||||
-sb ) bundle="on"
|
||||
;;
|
||||
-h ) usage
|
||||
exit
|
||||
;;
|
||||
|
@ -40,5 +45,5 @@ cd .vs
|
|||
# clean up any old builds of msix modules
|
||||
find . -name *msix* -d | xargs rm -r
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$build $zlib -DMACOS=on ..
|
||||
cmake -DCMAKE_BUILD_TYPE=$build $zlib -DSKIP_BUNDLES=$bundle -DMACOS=on ..
|
||||
make
|
||||
|
|
12
makewin.cmd
12
makewin.cmd
|
@ -29,6 +29,7 @@ set validationParser="-DUSE_VALIDATION_PARSER=off"
|
|||
set zlib="-DUSE_SHARED_ZLIB=off"
|
||||
set parser="-DXML_PARSER=msxml6"
|
||||
set msvc="-DUSE_STATIC_MSVC=off"
|
||||
set bundle="-DSKIP_BUNDLES=off"
|
||||
|
||||
:parseArgs
|
||||
if /I "%~2" == "--debug" (
|
||||
|
@ -58,6 +59,12 @@ if /I "%~2" == "-sz" (
|
|||
if /I "%~2" == "-mt" (
|
||||
set msvc="-DUSE_STATIC_MSVC=on"
|
||||
)
|
||||
if /I "%~2" == "--skip-bundles" (
|
||||
set bundle="-DSKIP_BUNDLES=on"
|
||||
)
|
||||
if /I "%~2" == "-sb" (
|
||||
set bundle="-DSKIP_BUNDLES=on"
|
||||
)
|
||||
shift /2
|
||||
if not "%~2"=="" goto parseArgs
|
||||
|
||||
|
@ -66,8 +73,8 @@ cd .vs
|
|||
if exist CMakeFiles rd /s /q CMakeFiles
|
||||
if exist CMakeCache.txt del CMakeCache.txt
|
||||
|
||||
echo cmake -DWIN32=on -DCMAKE_BUILD_TYPE=%build% %validationParser% %zlib% %parser% %msvc% -G"NMake Makefiles" ..
|
||||
cmake -DWIN32=on -DCMAKE_BUILD_TYPE=%build% %validationParser% %zlib% %parser% %msvc% -G"NMake Makefiles" ..
|
||||
echo cmake -DWIN32=on -DCMAKE_BUILD_TYPE=%build% %validationParser% %zlib% %parser% %msvc% %bundle% -G"NMake Makefiles" ..
|
||||
cmake -DWIN32=on -DCMAKE_BUILD_TYPE=%build% %validationParser% %zlib% %parser% %msvc% %bundle% -G"NMake Makefiles" ..
|
||||
nmake
|
||||
|
||||
goto Exit
|
||||
|
@ -85,6 +92,7 @@ echo --parser-xerces, -px = use Xerces-C parser. Default MSXML6.
|
|||
echo --validation-parser, -vp = enable XML schema validation.
|
||||
echo --shared-zlib, -sz = don't statically link zlib.
|
||||
echo -mt = use compiler flag /MT to use static version of the run-time library.
|
||||
echo --skip-bundles, -sb = turn off bundle support.
|
||||
echo --help, -h, /? = print this usage information and exit.
|
||||
:Exit
|
||||
EXIT /B 0
|
||||
|
|
|
@ -28,7 +28,7 @@ add_executable(${BINARY_NAME}
|
|||
set_property(TARGET ${BINARY_NAME} PROPERTY CXX_STANDARD 14)
|
||||
|
||||
ADD_DEPENDENCIES(${BINARY_NAME} msix)
|
||||
if (LINUX)
|
||||
if (LINUX OR AOSP)
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE -latomic)
|
||||
endif()
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE msix)
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
//
|
||||
// Copyright (C) 2017 Microsoft. All rights reserved.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "AppxPackaging.hpp"
|
||||
#include "MSIXFactory.hpp"
|
||||
#include "ComHelper.hpp"
|
||||
#include "Applicability.hpp"
|
||||
#include "VerifierObject.hpp"
|
||||
|
||||
EXTERN_C const IID IID_IBundleInfo;
|
||||
#ifndef WIN32
|
||||
// {ff82ffcd-747a-4df9-8879-853ab9dd15a1}
|
||||
interface IBundleInfo : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IBundleInfo : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
virtual std::vector<MSIX::ComPtr<IAppxBundleManifestPackageInfo>>& GetPackages() = 0;
|
||||
};
|
||||
|
||||
EXTERN_C const IID IID_IAppxBundleManifestPackageInfoInternal;
|
||||
#ifndef WIN32
|
||||
// {32e6fcf0-729b-401d-9dbc-f927b494f9af}
|
||||
interface IAppxBundleManifestPackageInfoInternal : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IAppxBundleManifestPackageInfoInternal : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
virtual const std::string& GetFileName() = 0;
|
||||
virtual const std::vector<MSIX::Bcp47Tag>& GetLanguages() = 0;
|
||||
virtual const std::uint64_t GetOffset() = 0;
|
||||
virtual bool HasQualifiedResources() = 0;
|
||||
};
|
||||
|
||||
SpecializeUuidOfImpl(IAppxBundleManifestPackageInfoInternal);
|
||||
SpecializeUuidOfImpl(IBundleInfo);
|
||||
|
||||
namespace MSIX {
|
||||
class AppxBundleManifestObject final : public ComClass<AppxBundleManifestObject, IAppxBundleManifestReader, IVerifierObject, IBundleInfo>
|
||||
{
|
||||
public:
|
||||
AppxBundleManifestObject(IMsixFactory* factory, const ComPtr<IStream>& stream);
|
||||
|
||||
// IVerifierObject
|
||||
bool HasStream() override { return !!m_stream; }
|
||||
ComPtr<IStream> GetStream() override { return m_stream; }
|
||||
ComPtr<IStream> GetValidationStream(const std::string& part, const ComPtr<IStream>&) override { NOTSUPPORTED; }
|
||||
const std::string& GetPublisher() override { NOTSUPPORTED; }
|
||||
|
||||
// IAppxBundleManifestReader
|
||||
HRESULT STDMETHODCALLTYPE GetPackageId(IAppxManifestPackageId **packageId) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetPackageInfoItems(IAppxBundleManifestPackageInfoEnumerator **packageInfoItems) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetStream(IStream **manifestStream) noexcept override;
|
||||
|
||||
// IBundleInfo
|
||||
std::vector<ComPtr<IAppxBundleManifestPackageInfo>>& GetPackages() override { return m_packages; }
|
||||
|
||||
protected:
|
||||
IMsixFactory* m_factory;
|
||||
ComPtr<IStream> m_stream;
|
||||
ComPtr<IAppxManifestPackageId> m_packageId;
|
||||
std::vector<ComPtr<IAppxBundleManifestPackageInfo>> m_packages;
|
||||
};
|
||||
|
||||
class AppxBundleQualifiedResource final : public MSIX::ComClass<AppxBundleQualifiedResource, IAppxManifestQualifiedResource>
|
||||
{
|
||||
public:
|
||||
AppxBundleQualifiedResource(IMsixFactory* factory, const std::string& language) : m_factory(factory), m_language(language) {}
|
||||
|
||||
// IAppxManifestQualifiedResource
|
||||
HRESULT STDMETHODCALLTYPE GetLanguage(LPWSTR *language) noexcept override try
|
||||
{
|
||||
return m_factory->MarshalOutString(m_language, language);
|
||||
} CATCH_RETURN();
|
||||
|
||||
// For now we don't having other resources other than language
|
||||
HRESULT STDMETHODCALLTYPE GetScale(UINT32 *scale) noexcept override
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetDXFeatureLevel(DX_FEATURE_LEVEL *dxFeatureLevel) noexcept override
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
}
|
||||
|
||||
protected:
|
||||
IMsixFactory* m_factory;
|
||||
std::string m_language;
|
||||
};
|
||||
|
||||
class AppxBundleManifestPackageInfo final : public ComClass<AppxBundleManifestPackageInfo, IAppxBundleManifestPackageInfo, IAppxBundleManifestPackageInfoInternal>
|
||||
{
|
||||
public:
|
||||
AppxBundleManifestPackageInfo(
|
||||
IMsixFactory* factory,
|
||||
const std::string& name,
|
||||
const std::string& bundleName,
|
||||
const std::string& version,
|
||||
const std::uint64_t size,
|
||||
const std::uint64_t offset,
|
||||
const std::string& resourceId,
|
||||
const std::string& architecture,
|
||||
const std::string& publisherId,
|
||||
std::vector<Bcp47Tag>& languages,
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType);
|
||||
|
||||
// IAppxBundleManifestPackageInfo
|
||||
HRESULT STDMETHODCALLTYPE GetPackageType(APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE *packageType) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetPackageId(IAppxManifestPackageId **packageId) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetFileName(LPWSTR *fileName) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetOffset(UINT64 *offset) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetSize(UINT64 *size) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetResources(IAppxManifestQualifiedResourcesEnumerator **resources) noexcept override;
|
||||
|
||||
// IAppxBundleManifestPackageInfoInternal
|
||||
const std::string& GetFileName() override { return m_fileName; }
|
||||
const std::vector<Bcp47Tag>& GetLanguages() override { return m_languages; }
|
||||
const std::uint64_t GetOffset() override { return m_offset; }
|
||||
bool HasQualifiedResources() override { return !m_languages.empty(); }
|
||||
|
||||
private:
|
||||
IMsixFactory* m_factory;
|
||||
std::string m_fileName;
|
||||
ComPtr<IAppxManifestPackageId> m_packageId;
|
||||
std::uint64_t m_size;
|
||||
std::uint64_t m_offset;
|
||||
std::vector<Bcp47Tag> m_languages;
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE m_packageType = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION;
|
||||
};
|
||||
}
|
|
@ -32,22 +32,8 @@ public:
|
|||
virtual const MSIX_PLATFORMS GetPlatform() = 0;
|
||||
};
|
||||
|
||||
EXTERN_C const IID IID_IBundleInfo;
|
||||
#ifndef WIN32
|
||||
// {ff82ffcd-747a-4df9-8879-853ab9dd15a1}
|
||||
interface IBundleInfo : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IBundleInfo : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
virtual std::vector<MSIX::ComPtr<IAppxBundleManifestPackageInfo>>& GetPackages() = 0;
|
||||
};
|
||||
|
||||
SpecializeUuidOfImpl(IAppxManifestObject);
|
||||
SpecializeUuidOfImpl(IBundleInfo);
|
||||
|
||||
namespace MSIX {
|
||||
|
||||
|
@ -228,30 +214,4 @@ namespace MSIX {
|
|||
std::vector<ComPtr<IAppxManifestTargetDeviceFamily>> m_tdf;
|
||||
ComPtr<IXmlDom> m_dom;
|
||||
};
|
||||
|
||||
class AppxBundleManifestObject final : public ComClass<AppxBundleManifestObject, IAppxBundleManifestReader, IVerifierObject, IBundleInfo>
|
||||
{
|
||||
public:
|
||||
AppxBundleManifestObject(IMsixFactory* factory, const ComPtr<IStream>& stream);
|
||||
|
||||
// IVerifierObject
|
||||
bool HasStream() override { return !!m_stream; }
|
||||
ComPtr<IStream> GetStream() override { return m_stream; }
|
||||
ComPtr<IStream> GetValidationStream(const std::string& part, const ComPtr<IStream>&) override { NOTSUPPORTED; }
|
||||
const std::string& GetPublisher() override { NOTSUPPORTED; }
|
||||
|
||||
// IAppxBundleManifestReader
|
||||
HRESULT STDMETHODCALLTYPE GetPackageId(IAppxManifestPackageId **packageId) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetPackageInfoItems(IAppxBundleManifestPackageInfoEnumerator **packageInfoItems) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetStream(IStream **manifestStream) noexcept override;
|
||||
|
||||
// IBundleInfo
|
||||
std::vector<ComPtr<IAppxBundleManifestPackageInfo>>& GetPackages() override { return m_packages; }
|
||||
|
||||
protected:
|
||||
IMsixFactory* m_factory;
|
||||
ComPtr<IStream> m_stream;
|
||||
ComPtr<IAppxManifestPackageId> m_packageId;
|
||||
std::vector<ComPtr<IAppxBundleManifestPackageInfo>> m_packages;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
#include "ComHelper.hpp"
|
||||
#include "MSIXFactory.hpp"
|
||||
#include "Exceptions.hpp"
|
||||
#include "Applicability.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
EXTERN_C const IID IID_IAppxManifestPackageIdInternal;
|
||||
|
@ -33,25 +31,7 @@ public:
|
|||
virtual const std::string GetPackageFamilyName() = 0;
|
||||
};
|
||||
|
||||
EXTERN_C const IID IID_IAppxBundleManifestPackageInfoInternal;
|
||||
#ifndef WIN32
|
||||
// {32e6fcf0-729b-401d-9dbc-f927b494f9af}
|
||||
interface IAppxBundleManifestPackageInfoInternal : public IUnknown
|
||||
#else
|
||||
#include "Unknwn.h"
|
||||
#include "Objidl.h"
|
||||
class IAppxBundleManifestPackageInfoInternal : public IUnknown
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
virtual const std::string& GetFileName() = 0;
|
||||
virtual const std::vector<MSIX::Bcp47Tag>& GetLanguages() = 0;
|
||||
virtual const std::uint64_t GetOffset() = 0;
|
||||
virtual bool HasQualifiedResources() = 0;
|
||||
};
|
||||
|
||||
SpecializeUuidOfImpl(IAppxManifestPackageIdInternal);
|
||||
SpecializeUuidOfImpl(IAppxBundleManifestPackageInfoInternal);
|
||||
|
||||
namespace MSIX {
|
||||
|
||||
|
@ -152,71 +132,4 @@ namespace MSIX {
|
|||
std::string m_publisherId;
|
||||
std::string m_publisher;
|
||||
};
|
||||
|
||||
class AppxBundleQualifiedResource final : public MSIX::ComClass<AppxBundleQualifiedResource, IAppxManifestQualifiedResource>
|
||||
{
|
||||
public:
|
||||
AppxBundleQualifiedResource(IMsixFactory* factory, const std::string& language) : m_factory(factory), m_language(language) {}
|
||||
|
||||
// IAppxManifestQualifiedResource
|
||||
HRESULT STDMETHODCALLTYPE GetLanguage(LPWSTR *language) noexcept override try
|
||||
{
|
||||
return m_factory->MarshalOutString(m_language, language);
|
||||
} CATCH_RETURN();
|
||||
|
||||
// For now we don't having other resources other than language
|
||||
HRESULT STDMETHODCALLTYPE GetScale(UINT32 *scale) noexcept override
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetDXFeatureLevel(DX_FEATURE_LEVEL *dxFeatureLevel) noexcept override
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
}
|
||||
|
||||
protected:
|
||||
IMsixFactory* m_factory;
|
||||
std::string m_language;
|
||||
};
|
||||
|
||||
class AppxBundleManifestPackageInfo final : public ComClass<AppxBundleManifestPackageInfo, IAppxBundleManifestPackageInfo, IAppxBundleManifestPackageInfoInternal>
|
||||
{
|
||||
public:
|
||||
AppxBundleManifestPackageInfo(
|
||||
IMsixFactory* factory,
|
||||
const std::string& name,
|
||||
const std::string& bundleName,
|
||||
const std::string& version,
|
||||
const std::uint64_t size,
|
||||
const std::uint64_t offset,
|
||||
const std::string& resourceId,
|
||||
const std::string& architecture,
|
||||
const std::string& publisherId,
|
||||
std::vector<Bcp47Tag>& languages,
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType);
|
||||
|
||||
// IAppxBundleManifestPackageInfo
|
||||
HRESULT STDMETHODCALLTYPE GetPackageType(APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE *packageType) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetPackageId(IAppxManifestPackageId **packageId) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetFileName(LPWSTR *fileName) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetOffset(UINT64 *offset) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetSize(UINT64 *size) noexcept override;
|
||||
HRESULT STDMETHODCALLTYPE GetResources(IAppxManifestQualifiedResourcesEnumerator **resources) noexcept override;
|
||||
|
||||
// IAppxBundleManifestPackageInfoInternal
|
||||
const std::string& GetFileName() override { return m_fileName; }
|
||||
const std::vector<Bcp47Tag>& GetLanguages() override { return m_languages; }
|
||||
const std::uint64_t GetOffset() override { return m_offset; }
|
||||
bool HasQualifiedResources() override { return !m_languages.empty(); }
|
||||
|
||||
private:
|
||||
IMsixFactory* m_factory;
|
||||
std::string m_fileName;
|
||||
ComPtr<IAppxManifestPackageId> m_packageId;
|
||||
std::uint64_t m_size;
|
||||
std::uint64_t m_offset;
|
||||
std::vector<Bcp47Tag> m_languages;
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE m_packageType = APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -78,12 +78,14 @@ namespace MSIX {
|
|||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if (riid == UuidOfImpl<IAppxBundleReader>::iid && m_isBundle)
|
||||
{
|
||||
*ppvObject = static_cast<void*>(static_cast<IAppxBundleReader*>(this));
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
#endif //BUNDLE_SUPPORT
|
||||
if (riid == UuidOfImpl<IUnknown>::iid)
|
||||
{
|
||||
*ppvObject = static_cast<void*>(reinterpret_cast<IUnknown*>(this));
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
//
|
||||
// Copyright (C) 2017 Microsoft. All rights reserved.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#include "AppxBundleManifest.hpp"
|
||||
#include "AppxPackageInfo.hpp"
|
||||
#include "ComHelper.hpp"
|
||||
#include "Enumerators.hpp"
|
||||
#include "Encoding.hpp"
|
||||
#include "IXml.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace MSIX {
|
||||
|
||||
AppxBundleManifestObject::AppxBundleManifestObject(IMsixFactory* factory, const ComPtr<IStream>& stream) : m_factory(factory), m_stream(stream)
|
||||
{
|
||||
ComPtr<IXmlFactory> xmlFactory;
|
||||
ThrowHrIfFailed(m_factory->QueryInterface(UuidOfImpl<IXmlFactory>::iid, reinterpret_cast<void**>(&xmlFactory)));
|
||||
auto dom = xmlFactory->CreateDomFromStream(XmlContentType::AppxBundleManifestXml, stream);
|
||||
XmlVisitor visitorIdentity(static_cast<void*>(this), [](void* s, const ComPtr<IXmlElement>& identityNode)->bool
|
||||
{
|
||||
AppxBundleManifestObject* self = reinterpret_cast<AppxBundleManifestObject*>(s);
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (nullptr != self->m_packageId.Get()), "There must be only one Identity element at most in AppxBundleManifest.xml");
|
||||
|
||||
const auto& name = identityNode->GetAttributeValue(XmlAttributeName::Name);
|
||||
const auto& publisher = identityNode->GetAttributeValue(XmlAttributeName::Publisher);
|
||||
const auto& version = identityNode->GetAttributeValue(XmlAttributeName::Version);
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (publisher.empty()), "Invalid Identity element");
|
||||
// Bundles don't have a ResourceId attribute in their manifest, but is always ~ for the package identity.
|
||||
self->m_packageId = ComPtr<IAppxManifestPackageId>::Make<AppxManifestPackageId>(self->m_factory, name, version, "~", "neutral", publisher);
|
||||
return true;
|
||||
});
|
||||
dom->ForEachElementIn(dom->GetDocument(), XmlQueryName::Bundle_Identity, visitorIdentity);
|
||||
|
||||
struct _context
|
||||
{
|
||||
AppxBundleManifestObject* self;
|
||||
IXmlDom* dom;
|
||||
std::vector<std::string> packageNames;
|
||||
size_t mainPackages;
|
||||
};
|
||||
_context context = { this, dom.Get(), {} , 0};
|
||||
|
||||
XmlVisitor visitorPackages(static_cast<void*>(&context), [](void* c, const ComPtr<IXmlElement>& packageNode)->bool
|
||||
{
|
||||
_context* context = reinterpret_cast<_context*>(c);
|
||||
const auto& name = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_FileName);
|
||||
|
||||
std::ostringstream builder;
|
||||
builder << "Duplicate file: '" << name << "' specified in AppxBundleManifest.xml.";
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError,
|
||||
std::find(std::begin(context->packageNames), std::end(context->packageNames), name) != context->packageNames.end(),
|
||||
builder.str().c_str());
|
||||
context->packageNames.push_back(name);
|
||||
|
||||
const auto& version = packageNode->GetAttributeValue(XmlAttributeName::Version);
|
||||
const auto& resourceId = packageNode->GetAttributeValue(XmlAttributeName::ResourceId);
|
||||
const auto& architecture = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_Architecture);
|
||||
const auto& type = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_Type);
|
||||
const auto size = GetNumber<std::uint64_t>(packageNode, XmlAttributeName::Size, 0);
|
||||
const auto offset = GetNumber<std::uint64_t>(packageNode, XmlAttributeName::Bundle_Package_Offset, 0);
|
||||
|
||||
// Default value is resource
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType = (type.empty() || type == "resource") ?
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE : APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION;
|
||||
|
||||
struct _resourcesContext
|
||||
{
|
||||
std::vector<Bcp47Tag> languages;
|
||||
bool hasResources;
|
||||
};
|
||||
_resourcesContext resourcesContext = { {}, false};
|
||||
XmlVisitor visitor(static_cast<void*>(&resourcesContext), [](void* c, const ComPtr<IXmlElement>& resourceNode)->bool
|
||||
{
|
||||
_resourcesContext* resourcesContext = reinterpret_cast<_resourcesContext*>(c);
|
||||
const auto& language = resourceNode->GetAttributeValue(XmlAttributeName::Language);
|
||||
if (!language.empty()) { resourcesContext->languages.push_back(Bcp47Tag(language)); }
|
||||
resourcesContext->hasResources = true;
|
||||
return true;
|
||||
});
|
||||
context->dom->ForEachElementIn(packageNode, XmlQueryName::Bundle_Packages_Package_Resources_Resource, visitor);
|
||||
|
||||
if ((packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE) && resourcesContext.languages.empty() && resourcesContext.hasResources)
|
||||
{ // For now, we only support languages resource packages
|
||||
return true;
|
||||
}
|
||||
|
||||
ComPtr<IAppxManifestPackageIdInternal> packageIdInternal = context->self->m_packageId.As<IAppxManifestPackageIdInternal>();
|
||||
auto package = ComPtr<IAppxBundleManifestPackageInfo>::Make<AppxBundleManifestPackageInfo>(
|
||||
context->self->m_factory, name, packageIdInternal->GetName(), version, size, offset, resourceId,
|
||||
architecture, packageIdInternal->GetPublisher(), resourcesContext.languages, packageType);
|
||||
context->self->m_packages.push_back(std::move(package));
|
||||
|
||||
if(packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION)
|
||||
{
|
||||
context->mainPackages++;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
dom->ForEachElementIn(dom->GetDocument(), XmlQueryName::Bundle_Packages_Package, visitorPackages);
|
||||
ThrowErrorIf(Error::XmlError, (context.packageNames.size() == 0), "No packages in AppxBundleManifest.xml");
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (context.mainPackages == 0), "Bundle contains only resource packages");
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetPackageId(IAppxManifestPackageId **packageId) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageId == nullptr || *packageId != nullptr), "bad pointer");
|
||||
auto package = m_packageId;
|
||||
*packageId = package.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetPackageInfoItems(IAppxBundleManifestPackageInfoEnumerator **packageInfoItems) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageInfoItems == nullptr || *packageInfoItems != nullptr), "bad pointer.");
|
||||
*packageInfoItems = ComPtr<IAppxBundleManifestPackageInfoEnumerator>::
|
||||
Make<EnumeratorCom<IAppxBundleManifestPackageInfoEnumerator, IAppxBundleManifestPackageInfo>>(m_packages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetStream(IStream **manifestStream) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (manifestStream == nullptr || *manifestStream != nullptr), "bad pointer");
|
||||
auto stream = GetStream();
|
||||
LARGE_INTEGER li{0};
|
||||
ThrowHrIfFailed(stream->Seek(li, StreamBase::Reference::START, nullptr));
|
||||
*manifestStream = stream.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
AppxBundleManifestPackageInfo::AppxBundleManifestPackageInfo(
|
||||
IMsixFactory* factory,
|
||||
const std::string& name,
|
||||
const std::string& bundleName,
|
||||
const std::string& version,
|
||||
const std::uint64_t size,
|
||||
const std::uint64_t offset,
|
||||
const std::string& resourceId,
|
||||
const std::string& architecture,
|
||||
const std::string& publisher,
|
||||
std::vector<Bcp47Tag>& languages,
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType):
|
||||
m_factory(factory), m_fileName(name), m_size(size), m_offset(offset), m_languages(std::move(languages)), m_packageType(packageType)
|
||||
{
|
||||
std::regex e (".+\\.((appx)|(msix))");
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, !std::regex_match(m_fileName, e), "Invalid FileName attribute in AppxBundleManifest.xml");
|
||||
m_packageId = ComPtr<IAppxManifestPackageId>::Make<AppxManifestPackageId>(factory, bundleName, version, resourceId, architecture, publisher);
|
||||
}
|
||||
|
||||
// IAppxBundleManifestPackageInfo
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetPackageType(APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE *packageType) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageType == nullptr), "bad pointer");
|
||||
*packageType = m_packageType;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetPackageId(IAppxManifestPackageId **packageId) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageId == nullptr || *packageId != nullptr), "bad pointer");
|
||||
auto package = m_packageId;
|
||||
*packageId = package.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetFileName(LPWSTR *fileName) noexcept try
|
||||
{
|
||||
return m_factory->MarshalOutString(m_fileName, fileName);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetOffset(UINT64 *offset) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (offset == nullptr), "bad pointer");
|
||||
*offset = m_offset;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetSize(UINT64 *size) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (size == nullptr), "bad pointer");
|
||||
*size = m_size;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetResources(IAppxManifestQualifiedResourcesEnumerator **resources) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (resources == nullptr || *resources != nullptr), "bad pointer.");
|
||||
std::vector<ComPtr<IAppxManifestQualifiedResource>> languages;
|
||||
for(auto& bcp47 : m_languages)
|
||||
{
|
||||
auto resource = ComPtr<IAppxManifestQualifiedResource>::Make<AppxBundleQualifiedResource>(m_factory, bcp47.GetFullTag());
|
||||
languages.push_back(std::move(resource));
|
||||
}
|
||||
*resources = ComPtr<IAppxManifestQualifiedResourcesEnumerator>::
|
||||
Make<EnumeratorCom<IAppxManifestQualifiedResourcesEnumerator, IAppxManifestQualifiedResource>>(languages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
}
|
|
@ -84,21 +84,33 @@ namespace MSIX {
|
|||
// IAppxBundleFactory
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateBundleWriter(IStream *outputStream, UINT64 bundleVersion, IAppxBundleWriter **bundleWriter) noexcept
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateBundleReader(IStream *inputStream, IAppxBundleReader **bundleReader) noexcept try
|
||||
{
|
||||
ComPtr<IAppxPackageReader> reader;
|
||||
ThrowHrIfFailed(CreatePackageReader(inputStream, &reader));
|
||||
auto result = reader.As<IAppxBundleReader>();
|
||||
*bundleReader = result.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
ComPtr<IAppxPackageReader> reader;
|
||||
ThrowHrIfFailed(CreatePackageReader(inputStream, &reader));
|
||||
auto result = reader.As<IAppxBundleReader>();
|
||||
*bundleReader = result.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxFactory::CreateBundleManifestReader(IStream *inputStream, IAppxBundleManifestReader **manifestReader) noexcept
|
||||
{
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
return static_cast<HRESULT>(Error::NotImplemented);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
}
|
||||
|
||||
// IMsixFactory
|
||||
|
|
|
@ -376,120 +376,4 @@ namespace MSIX {
|
|||
*documentElement = m_dom->GetDocument().As<IMsixElement>().Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
AppxBundleManifestObject::AppxBundleManifestObject(IMsixFactory* factory, const ComPtr<IStream>& stream) : m_factory(factory), m_stream(stream)
|
||||
{
|
||||
ComPtr<IXmlFactory> xmlFactory;
|
||||
ThrowHrIfFailed(m_factory->QueryInterface(UuidOfImpl<IXmlFactory>::iid, reinterpret_cast<void**>(&xmlFactory)));
|
||||
auto dom = xmlFactory->CreateDomFromStream(XmlContentType::AppxBundleManifestXml, stream);
|
||||
XmlVisitor visitorIdentity(static_cast<void*>(this), [](void* s, const ComPtr<IXmlElement>& identityNode)->bool
|
||||
{
|
||||
AppxBundleManifestObject* self = reinterpret_cast<AppxBundleManifestObject*>(s);
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (nullptr != self->m_packageId.Get()), "There must be only one Identity element at most in AppxBundleManifest.xml");
|
||||
|
||||
const auto& name = identityNode->GetAttributeValue(XmlAttributeName::Name);
|
||||
const auto& publisher = identityNode->GetAttributeValue(XmlAttributeName::Publisher);
|
||||
const auto& version = identityNode->GetAttributeValue(XmlAttributeName::Version);
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (publisher.empty()), "Invalid Identity element");
|
||||
// Bundles don't have a ResourceId attribute in their manifest, but is always ~ for the package identity.
|
||||
self->m_packageId = ComPtr<IAppxManifestPackageId>::Make<AppxManifestPackageId>(self->m_factory, name, version, "~", "neutral", publisher);
|
||||
return true;
|
||||
});
|
||||
dom->ForEachElementIn(dom->GetDocument(), XmlQueryName::Bundle_Identity, visitorIdentity);
|
||||
|
||||
struct _context
|
||||
{
|
||||
AppxBundleManifestObject* self;
|
||||
IXmlDom* dom;
|
||||
std::vector<std::string> packageNames;
|
||||
size_t mainPackages;
|
||||
};
|
||||
_context context = { this, dom.Get(), {} , 0};
|
||||
|
||||
XmlVisitor visitorPackages(static_cast<void*>(&context), [](void* c, const ComPtr<IXmlElement>& packageNode)->bool
|
||||
{
|
||||
_context* context = reinterpret_cast<_context*>(c);
|
||||
const auto& name = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_FileName);
|
||||
|
||||
std::ostringstream builder;
|
||||
builder << "Duplicate file: '" << name << "' specified in AppxBundleManifest.xml.";
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError,
|
||||
std::find(std::begin(context->packageNames), std::end(context->packageNames), name) != context->packageNames.end(),
|
||||
builder.str().c_str());
|
||||
context->packageNames.push_back(name);
|
||||
|
||||
const auto& version = packageNode->GetAttributeValue(XmlAttributeName::Version);
|
||||
const auto& resourceId = packageNode->GetAttributeValue(XmlAttributeName::ResourceId);
|
||||
const auto& architecture = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_Architecture);
|
||||
const auto& type = packageNode->GetAttributeValue(XmlAttributeName::Bundle_Package_Type);
|
||||
const auto size = GetNumber<std::uint64_t>(packageNode, XmlAttributeName::Size, 0);
|
||||
const auto offset = GetNumber<std::uint64_t>(packageNode, XmlAttributeName::Bundle_Package_Offset, 0);
|
||||
|
||||
// Default value is resource
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType = (type.empty() || type == "resource") ?
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE : APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION;
|
||||
|
||||
struct _resourcesContext
|
||||
{
|
||||
std::vector<Bcp47Tag> languages;
|
||||
bool hasResources;
|
||||
};
|
||||
_resourcesContext resourcesContext = { {}, false};
|
||||
XmlVisitor visitor(static_cast<void*>(&resourcesContext), [](void* c, const ComPtr<IXmlElement>& resourceNode)->bool
|
||||
{
|
||||
_resourcesContext* resourcesContext = reinterpret_cast<_resourcesContext*>(c);
|
||||
const auto& language = resourceNode->GetAttributeValue(XmlAttributeName::Language);
|
||||
if (!language.empty()) { resourcesContext->languages.push_back(Bcp47Tag(language)); }
|
||||
resourcesContext->hasResources = true;
|
||||
return true;
|
||||
});
|
||||
context->dom->ForEachElementIn(packageNode, XmlQueryName::Bundle_Packages_Package_Resources_Resource, visitor);
|
||||
|
||||
if ((packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_RESOURCE) && resourcesContext.languages.empty() && resourcesContext.hasResources)
|
||||
{ // For now, we only support languages resource packages
|
||||
return true;
|
||||
}
|
||||
|
||||
ComPtr<IAppxManifestPackageIdInternal> packageIdInternal = context->self->m_packageId.As<IAppxManifestPackageIdInternal>();
|
||||
auto package = ComPtr<IAppxBundleManifestPackageInfo>::Make<AppxBundleManifestPackageInfo>(
|
||||
context->self->m_factory, name, packageIdInternal->GetName(), version, size, offset, resourceId,
|
||||
architecture, packageIdInternal->GetPublisher(), resourcesContext.languages, packageType);
|
||||
context->self->m_packages.push_back(std::move(package));
|
||||
|
||||
if(packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION)
|
||||
{
|
||||
context->mainPackages++;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
dom->ForEachElementIn(dom->GetDocument(), XmlQueryName::Bundle_Packages_Package, visitorPackages);
|
||||
ThrowErrorIf(Error::XmlError, (context.packageNames.size() == 0), "No packages in AppxBundleManifest.xml");
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, (context.mainPackages == 0), "Bundle contains only resource packages");
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetPackageId(IAppxManifestPackageId **packageId) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageId == nullptr || *packageId != nullptr), "bad pointer");
|
||||
auto package = m_packageId;
|
||||
*packageId = package.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetPackageInfoItems(IAppxBundleManifestPackageInfoEnumerator **packageInfoItems) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageInfoItems == nullptr || *packageInfoItems != nullptr), "bad pointer.");
|
||||
*packageInfoItems = ComPtr<IAppxBundleManifestPackageInfoEnumerator>::
|
||||
Make<EnumeratorCom<IAppxBundleManifestPackageInfoEnumerator, IAppxBundleManifestPackageInfo>>(m_packages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestObject::GetStream(IStream **manifestStream) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (manifestStream == nullptr || *manifestStream != nullptr), "bad pointer");
|
||||
auto stream = GetStream();
|
||||
LARGE_INTEGER li{0};
|
||||
ThrowHrIfFailed(stream->Seek(li, StreamBase::Reference::START, nullptr));
|
||||
*manifestStream = stream.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
}
|
||||
|
|
|
@ -172,72 +172,4 @@ namespace MSIX {
|
|||
ThrowErrorIfNot(Error::Unexpected, SHA256::ComputeHash(buffer.data(), static_cast<uint32_t>(buffer.size()), hash), "Failed computing publisherId");
|
||||
return Base32Encoding(hash);
|
||||
}
|
||||
|
||||
AppxBundleManifestPackageInfo::AppxBundleManifestPackageInfo(
|
||||
IMsixFactory* factory,
|
||||
const std::string& name,
|
||||
const std::string& bundleName,
|
||||
const std::string& version,
|
||||
const std::uint64_t size,
|
||||
const std::uint64_t offset,
|
||||
const std::string& resourceId,
|
||||
const std::string& architecture,
|
||||
const std::string& publisher,
|
||||
std::vector<Bcp47Tag>& languages,
|
||||
APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType):
|
||||
m_factory(factory), m_fileName(name), m_size(size), m_offset(offset), m_languages(std::move(languages)), m_packageType(packageType)
|
||||
{
|
||||
std::regex e (".+\\.((appx)|(msix))");
|
||||
ThrowErrorIf(Error::AppxManifestSemanticError, !std::regex_match(m_fileName, e), "Invalid FileName attribute in AppxBundleManifest.xml");
|
||||
m_packageId = ComPtr<IAppxManifestPackageId>::Make<AppxManifestPackageId>(factory, bundleName, version, resourceId, architecture, publisher);
|
||||
}
|
||||
|
||||
// IAppxBundleManifestPackageInfo
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetPackageType(APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE *packageType) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageType == nullptr), "bad pointer");
|
||||
*packageType = m_packageType;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetPackageId(IAppxManifestPackageId **packageId) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (packageId == nullptr || *packageId != nullptr), "bad pointer");
|
||||
auto package = m_packageId;
|
||||
*packageId = package.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetFileName(LPWSTR *fileName) noexcept try
|
||||
{
|
||||
return m_factory->MarshalOutString(m_fileName, fileName);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetOffset(UINT64 *offset) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (offset == nullptr), "bad pointer");
|
||||
*offset = m_offset;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetSize(UINT64 *size) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (size == nullptr), "bad pointer");
|
||||
*size = m_size;
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxBundleManifestPackageInfo::GetResources(IAppxManifestQualifiedResourcesEnumerator **resources) noexcept try
|
||||
{
|
||||
ThrowErrorIf(Error::InvalidParameter, (resources == nullptr || *resources != nullptr), "bad pointer.");
|
||||
std::vector<ComPtr<IAppxManifestQualifiedResource>> languages;
|
||||
for(auto& bcp47 : m_languages)
|
||||
{
|
||||
auto resource = ComPtr<IAppxManifestQualifiedResource>::Make<AppxBundleQualifiedResource>(m_factory, bcp47.GetFullTag());
|
||||
languages.push_back(std::move(resource));
|
||||
}
|
||||
*resources = ComPtr<IAppxManifestQualifiedResourcesEnumerator>::
|
||||
Make<EnumeratorCom<IAppxManifestQualifiedResourcesEnumerator, IAppxManifestQualifiedResource>>(languages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
} CATCH_RETURN();
|
||||
}
|
||||
|
|
|
@ -11,12 +11,16 @@
|
|||
#include "UnicodeConversion.hpp"
|
||||
#include "IXml.hpp"
|
||||
#include "MSIXResource.hpp"
|
||||
#include "Applicability.hpp"
|
||||
#include "AppxManifestObject.hpp"
|
||||
#include "Encoding.hpp"
|
||||
#include "Enumerators.hpp"
|
||||
#include "AppxFile.hpp"
|
||||
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
#include "Applicability.hpp"
|
||||
#include "AppxBundleManifest.hpp"
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
@ -95,11 +99,18 @@ namespace MSIX {
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string pathInWindows(APPXBUNDLEMANIFEST_XML);
|
||||
std::replace(pathInWindows.begin(), pathInWindows.end(), '/', '\\');
|
||||
stream = m_appxBlockMap->GetValidationStream(pathInWindows, appxBundleManifestInContainer);
|
||||
m_appxBundleManifest = ComPtr<IVerifierObject>::Make<AppxBundleManifestObject>(factory, stream);
|
||||
m_isBundle = true;
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
std::string pathInWindows(APPXBUNDLEMANIFEST_XML);
|
||||
std::replace(pathInWindows.begin(), pathInWindows.end(), '/', '\\');
|
||||
stream = m_appxBlockMap->GetValidationStream(pathInWindows, appxBundleManifestInContainer);
|
||||
m_appxBundleManifest = ComPtr<IVerifierObject>::Make<AppxBundleManifestObject>(factory, stream);
|
||||
m_isBundle = true;
|
||||
#else
|
||||
// It is valid for a user to create an IAppxPackageReader and then QI for IAppxBundleReader, but
|
||||
// not when bundle support is off.
|
||||
ThrowErrorAndLog(Error::NotSupported, "Bundle functionality not supported");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if ((m_validation & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) == 0)
|
||||
|
@ -193,6 +204,8 @@ namespace MSIX {
|
|||
|
||||
auto blockMapInternal = m_appxBlockMap.As<IAppxBlockMapInternal>();
|
||||
auto blockMapFiles = blockMapInternal->GetFileNames();
|
||||
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if(m_isBundle)
|
||||
{
|
||||
// There should only be one file in the blockmap for bundles. We validate that the block map contains
|
||||
|
@ -305,6 +318,7 @@ namespace MSIX {
|
|||
}
|
||||
else
|
||||
{
|
||||
#endif // BUNDLE_SUPPORT
|
||||
for (const auto& fileName : blockMapFiles)
|
||||
{ auto footPrintFile = std::find(std::begin(footPrintFileNames), std::end(footPrintFileNames), fileName);
|
||||
if (footPrintFile == std::end(footPrintFileNames))
|
||||
|
@ -323,7 +337,9 @@ namespace MSIX {
|
|||
// If the map is not empty, there's a file in the container that didn't go to the footprint or payload
|
||||
// files. (eg. payload file missing in the AppxBlockMap.xml)
|
||||
ThrowErrorIfNot(Error::BlockMapSemanticError, (filesToProcess.empty()), "Payload file not described in AppxBlockMap.xml");
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Verify file in OPC and BlockMap
|
||||
|
@ -405,6 +421,8 @@ namespace MSIX {
|
|||
ThrowHrIfFailed(sourceFile->CopyTo(targetFile.Get(), bytesCount, nullptr, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if(m_isBundle)
|
||||
{
|
||||
for(const auto& appx : m_applicablePackages)
|
||||
|
@ -413,6 +431,7 @@ namespace MSIX {
|
|||
static_cast<MSIX_PACKUNPACK_OPTION>(options | MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER), to.Get());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// IStorageObject
|
||||
|
@ -531,58 +550,74 @@ namespace MSIX {
|
|||
// IAppxBundleReader
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetFootprintFile(APPX_BUNDLE_FOOTPRINT_FILE_TYPE fileType, IAppxFile **footprintFile) noexcept try
|
||||
{
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter, (footprintFile == nullptr || *footprintFile != nullptr), "bad pointer");
|
||||
ThrowErrorIf(Error::FileNotFound, (static_cast<size_t>(fileType) > bundleFootprintFiles.size()), "unknown footprint file type");
|
||||
std::string footprint (bundleFootprintFiles[fileType]);
|
||||
auto result = GetAppxFile(footprint);
|
||||
ThrowErrorIfNot(Error::FileNotFound, result, "Requested footprint file not in bundle")
|
||||
// Clients expect the stream's pointer to be at the start of the file!
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(result->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
*footprintFile = result.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter, (footprintFile == nullptr || *footprintFile != nullptr), "bad pointer");
|
||||
ThrowErrorIf(Error::FileNotFound, (static_cast<size_t>(fileType) > bundleFootprintFiles.size()), "unknown footprint file type");
|
||||
std::string footprint (bundleFootprintFiles[fileType]);
|
||||
auto result = GetAppxFile(footprint);
|
||||
ThrowErrorIfNot(Error::FileNotFound, result, "Requested footprint file not in bundle")
|
||||
// Clients expect the stream's pointer to be at the start of the file!
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(result->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
*footprintFile = result.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetPayloadPackages(IAppxFilesEnumerator **payloadPackages) noexcept try
|
||||
{
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter,(payloadPackages == nullptr || *payloadPackages != nullptr), "bad pointer");
|
||||
std::vector<ComPtr<IAppxFile>> packages;
|
||||
for (const auto& fileName : GetFileNames(FileNameOptions::PayloadOnly))
|
||||
{
|
||||
auto package = GetAppxFile(fileName);
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(package->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
packages.push_back(std::move(package));
|
||||
}
|
||||
*payloadPackages = ComPtr<IAppxFilesEnumerator>::
|
||||
Make<EnumeratorCom<IAppxFilesEnumerator, IAppxFile>>(packages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter,(payloadPackages == nullptr || *payloadPackages != nullptr), "bad pointer");
|
||||
std::vector<ComPtr<IAppxFile>> packages;
|
||||
for (const auto& fileName : GetFileNames(FileNameOptions::PayloadOnly))
|
||||
{
|
||||
auto package = GetAppxFile(fileName);
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(package->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
packages.push_back(std::move(package));
|
||||
}
|
||||
*payloadPackages = ComPtr<IAppxFilesEnumerator>::
|
||||
Make<EnumeratorCom<IAppxFilesEnumerator, IAppxFile>>(packages).Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetPayloadPackage(LPCWSTR fileName, IAppxFile **payloadPackage) noexcept try
|
||||
{
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter, (fileName == nullptr || payloadPackage == nullptr || *payloadPackage != nullptr), "bad pointer");
|
||||
std::string name = utf16_to_utf8(fileName);
|
||||
auto result = GetAppxFile(name);
|
||||
ThrowErrorIfNot(Error::FileNotFound, result, "Requested package not in bundle")
|
||||
// Clients expect the stream's pointer to be at the start of the file!
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(result->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
*payloadPackage = result.Detach();
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter, (fileName == nullptr || payloadPackage == nullptr || *payloadPackage != nullptr), "bad pointer");
|
||||
std::string name = utf16_to_utf8(fileName);
|
||||
auto result = GetAppxFile(name);
|
||||
ThrowErrorIfNot(Error::FileNotFound, result, "Requested package not in bundle")
|
||||
// Clients expect the stream's pointer to be at the start of the file!
|
||||
ComPtr<IStream> stream;
|
||||
ThrowHrIfFailed(result->GetStream(&stream));
|
||||
ThrowHrIfFailed(stream->Seek({0}, StreamBase::Reference::START, nullptr));
|
||||
*payloadPackage = result.Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetManifest(IAppxBundleManifestReader **manifestReader) noexcept
|
||||
{
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter,(manifestReader == nullptr || *manifestReader != nullptr), "bad pointer");
|
||||
*manifestReader = m_appxBundleManifest.As<IAppxBundleManifestReader>().Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
if (!m_isBundle) { return static_cast<HRESULT>(Error::NotImplemented); }
|
||||
ThrowErrorIf(Error::InvalidParameter,(manifestReader == nullptr || *manifestReader != nullptr), "bad pointer");
|
||||
*manifestReader = m_appxBundleManifest.As<IAppxBundleManifestReader>().Detach();
|
||||
return static_cast<HRESULT>(Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -88,12 +88,16 @@ MIDL_DEFINE_GUID(IID, IID_IXmlElement, 0xac94449e,0x442d,0x4bed,0x8f,0
|
|||
MIDL_DEFINE_GUID(IID, IID_IXmlDom, 0x0e7a446e,0xbaf7,0x44c1,0xb3,0x8a,0x21,0x6b,0xfa,0x18,0xa1,0xa8);
|
||||
MIDL_DEFINE_GUID(IID, IID_IXmlFactory, 0xf82a60ec,0xfbfc,0x4cb9,0xbc,0x04,0x1a,0x0f,0xe2,0xb4,0xd5,0xbe);
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxBlockMapInternal, 0x67fed21a,0x70ef,0x4175,0x8f,0x12,0x41,0x5b,0x21,0x3a,0xb6,0xd2);
|
||||
MIDL_DEFINE_GUID(IID, IID_IBundleInfo, 0xff82ffcd,0x747a,0x4df9,0x88,0x79,0x85,0x3a,0xb9,0xdd,0x15,0xa1);
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxManifestObject, 0xeff6d561,0xa236,0x4058,0x9f,0x1d,0x8f,0x93,0x63,0x3f,0xba,0x4b);
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxManifestPackageIdInternal, 0x76b7d3e1,0x768a,0x45cb,0x96,0x26,0xba,0x64,0x52,0xbe,0xd2,0xde);
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxBundleManifestPackageInfoInternal, 0x32e6fcf0,0x729b,0x401d,0x9d,0xbc,0xf9,0x27,0xb4,0x94,0xf9,0xaf);
|
||||
MIDL_DEFINE_GUID(IID, IID_IStreamInternal, 0x44d2a7a8,0xa165,0x4a6e,0xa5,0x6f,0xc7,0xc2,0x4d,0xe7,0x50,0x5c);
|
||||
|
||||
// Internal bundle interfaces
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
MIDL_DEFINE_GUID(IID, IID_IBundleInfo, 0xff82ffcd,0x747a,0x4df9,0x88,0x79,0x85,0x3a,0xb9,0xdd,0x15,0xa1);
|
||||
MIDL_DEFINE_GUID(IID, IID_IAppxBundleManifestPackageInfoInternal, 0x32e6fcf0,0x729b,0x401d,0x9d,0xbc,0xf9,0x27,0xb4,0x94,0xf9,0xaf);
|
||||
#endif
|
||||
|
||||
// internal XML PAL interfaces
|
||||
#ifdef USING_XERCES
|
||||
MIDL_DEFINE_GUID(IID, IID_IXercesElement, 0x07d6ee0e,0x2165,0x4b90,0x80,0x24,0xe1,0x76,0x29,0x1e,0x77,0xdd);
|
||||
|
|
|
@ -22,6 +22,12 @@ if(XML_PARSER MATCHES msxml6)
|
|||
add_definitions(-DUSING_MSXML=1)
|
||||
endif()
|
||||
|
||||
if(SKIP_BUNDLES)
|
||||
message(STATUS "Bundle support disabled.")
|
||||
else()
|
||||
add_definitions(-DBUNDLE_SUPPORT=1)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(DirectoryObject PAL/FileSystem/Win32/DirectoryObject.cpp)
|
||||
set(SHA256 PAL/SHA256/Win32/SHA256.cpp)
|
||||
|
@ -165,8 +171,21 @@ else()
|
|||
set(CompressionObjectCpp PAL/DataCompression/Zlib/CompressionObject.cpp)
|
||||
endif()
|
||||
|
||||
set(BundleHeaders)
|
||||
set(BundleSources)
|
||||
if(NOT SKIP_BUNDLES)
|
||||
list(APPEND BundleHeaders
|
||||
../inc/Applicability.hpp
|
||||
../inc/AppxBundleManifest.hpp
|
||||
)
|
||||
list(APPEND BundleSources
|
||||
AppxBundleManifest.cpp
|
||||
ApplicabilityCommon.cpp
|
||||
${Applicability}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(LIB_PRIVATE_HEADERS
|
||||
../inc/Applicability.hpp
|
||||
../inc/AppxBlockMapObject.hpp
|
||||
../inc/AppxFactory.hpp
|
||||
../inc/AppxFile.hpp
|
||||
|
@ -196,6 +215,7 @@ set(LIB_PRIVATE_HEADERS
|
|||
../inc/IXml.hpp
|
||||
../inc/ZipFileStream.hpp
|
||||
../inc/ZipObject.hpp
|
||||
${BundleHeaders}
|
||||
)
|
||||
|
||||
set(LIB_SOURCES
|
||||
|
@ -212,13 +232,12 @@ set(LIB_SOURCES
|
|||
UnicodeConversion.cpp
|
||||
msix.cpp
|
||||
ZipObject.cpp
|
||||
ApplicabilityCommon.cpp
|
||||
${DirectoryObject}
|
||||
${SHA256}
|
||||
${Signature}
|
||||
${XmlParser}
|
||||
${Applicability}
|
||||
${CompressionObjectCpp}
|
||||
${BundleSources}
|
||||
)
|
||||
|
||||
# Copy out public headers
|
||||
|
@ -300,29 +319,31 @@ endif()
|
|||
|
||||
if(AOSP)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE -latomic)
|
||||
find_package(Java REQUIRED)
|
||||
if(NOT ANDROID_SDK)
|
||||
if(NOT DEFINED ENV{ANDROID_HOME})
|
||||
message(FATAL_ERROR "ANDROID_HOME enviroment variable not found.")
|
||||
if(NOT SKIP_BUNDLES) # This will change when we have JNI functionality that is not bundle related.
|
||||
find_package(Java REQUIRED)
|
||||
if(NOT ANDROID_SDK)
|
||||
if(NOT DEFINED ENV{ANDROID_HOME})
|
||||
message(FATAL_ERROR "ANDROID_HOME enviroment variable not found.")
|
||||
endif()
|
||||
set(ANDROID_SDK $ENV{ANDROID_HOME})
|
||||
endif()
|
||||
set(ANDROID_SDK $ENV{ANDROID_HOME})
|
||||
if(NOT ANDROID_SDK_VERSION)
|
||||
SET(ANDROID_SDK_VERSION 24)
|
||||
endif()
|
||||
if(ANDROID_SDK_VERSION LESS 24)
|
||||
message(FATAL_ERROR "MSIX minimum Android SDK is 24")
|
||||
endif()
|
||||
include(UseJava)
|
||||
message(STATUS "Android SDK = ${ANDROID_SDK}")
|
||||
add_jar(${PROJECT_NAME}-jni
|
||||
SOURCES
|
||||
PAL/java/com/microsoft/msix/JniHelper.java
|
||||
INCLUDE_JARS
|
||||
${ANDROID_SDK}/platforms/android-${ANDROID_SDK_VERSION}/android.jar
|
||||
OUTPUT_DIR
|
||||
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
)
|
||||
endif()
|
||||
if(NOT ANDROID_SDK_VERSION)
|
||||
SET(ANDROID_SDK_VERSION 24)
|
||||
endif()
|
||||
if(ANDROID_SDK_VERSION LESS 24)
|
||||
message(FATAL_ERROR "MSIX minimum Android SDK is 24")
|
||||
endif()
|
||||
include(UseJava)
|
||||
message(STATUS "Android SDK = ${ANDROID_SDK}")
|
||||
add_jar(${PROJECT_NAME}-jni
|
||||
SOURCES
|
||||
PAL/java/com/microsoft/msix/JniHelper.java
|
||||
INCLUDE_JARS
|
||||
${ANDROID_SDK}/platforms/android-${ANDROID_SDK_VERSION}/android.jar
|
||||
OUTPUT_DIR
|
||||
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
)
|
||||
endif()
|
||||
|
||||
if((IOS) OR (MACOS))
|
||||
|
|
|
@ -101,6 +101,7 @@ MSIX_API HRESULT STDMETHODCALLTYPE UnpackBundle(
|
|||
char* utf8SourcePackage,
|
||||
char* utf8Destination) noexcept try
|
||||
{
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
ThrowErrorIfNot(MSIX::Error::InvalidParameter,
|
||||
(utf8SourcePackage != nullptr && utf8Destination != nullptr),
|
||||
"Invalid parameters"
|
||||
|
@ -120,6 +121,9 @@ MSIX_API HRESULT STDMETHODCALLTYPE UnpackBundle(
|
|||
auto to = MSIX::ComPtr<IStorageObject>::Make<MSIX::DirectoryObject>(utf8Destination);
|
||||
reader.As<IPackage>()->Unpack(packUnpackOptions, to.Get());
|
||||
return static_cast<HRESULT>(MSIX::Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
MSIX_API HRESULT STDMETHODCALLTYPE UnpackBundleFromStream(
|
||||
|
@ -129,6 +133,7 @@ MSIX_API HRESULT STDMETHODCALLTYPE UnpackBundleFromStream(
|
|||
IStream* stream,
|
||||
char* utf8Destination) noexcept try
|
||||
{
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
ThrowErrorIfNot(MSIX::Error::InvalidParameter,
|
||||
(stream != nullptr && utf8Destination != nullptr),
|
||||
"Invalid parameters"
|
||||
|
@ -145,6 +150,9 @@ MSIX_API HRESULT STDMETHODCALLTYPE UnpackBundleFromStream(
|
|||
auto to = MSIX::ComPtr<IStorageObject>::Make<MSIX::DirectoryObject>(utf8Destination);
|
||||
reader.As<IPackage>()->Unpack(packUnpackOptions, to.Get());
|
||||
return static_cast<HRESULT>(MSIX::Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
MSIX_API HRESULT STDMETHODCALLTYPE GetLogTextUTF8(COTASKMEMALLOC* memalloc, char** logText) noexcept try
|
||||
|
@ -210,8 +218,12 @@ MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxBundleFactoryWithHeap(
|
|||
MSIX_APPLICABILITY_OPTIONS applicabilityOptions,
|
||||
IAppxBundleFactory** appxBundleFactory) noexcept try
|
||||
{
|
||||
#ifdef BUNDLE_SUPPORT
|
||||
*appxBundleFactory = MSIX::ComPtr<IAppxBundleFactory>::Make<MSIX::AppxFactory>(validationOption, applicabilityOptions, memalloc, memfree).Detach();
|
||||
return static_cast<HRESULT>(MSIX::Error::OK);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
#endif
|
||||
} CATCH_RETURN();
|
||||
|
||||
// Call specific for Windows. Default to call CoTaskMemAlloc and CoTaskMemFree
|
||||
|
@ -220,7 +232,7 @@ MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxBundleFactory(
|
|||
MSIX_APPLICABILITY_OPTIONS applicabilityOptions,
|
||||
IAppxBundleFactory** appxBundleFactory) noexcept
|
||||
{
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32) && defined(BUNDLE_SUPPORT)
|
||||
return CoCreateAppxBundleFactoryWithHeap(CoTaskMemAlloc, CoTaskMemFree, validationOption, applicabilityOptions, appxBundleFactory);
|
||||
#else
|
||||
return static_cast<HRESULT>(MSIX::Error::NotSupported);
|
||||
|
|
Загрузка…
Ссылка в новой задаче