Merged PR 1424038: Rename CrossPlat files from appx to MSIX

This change contains the renaming from xPlatAppx to MSIX Packaging SDK

Binaries
- xPlatAppx.dll -> msix.dll
- MakexPlatAppx.exe -> makemsix.exe

Export rename
- UnpackAppx ->UnpackPackage

Related work items: #15704951
This commit is contained in:
Ruben Guerrero Samaniego 2018-02-13 21:25:38 +00:00
Родитель 90e3b3c7f9
Коммит 7e05b7959b
105 изменённых файлов: 521 добавлений и 581 удалений

Просмотреть файл

@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
MESSAGE (STATUS "--------------------------------")
MESSAGE (STATUS "xPlatAppx")
MESSAGE (STATUS "MSIX Packaging SDK")
MESSAGE (STATUS "--------------------------------")
# Set build options
@ -67,12 +67,12 @@ ENDIF()
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
SET(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
MESSAGE (STATUS "xPlatAppx version ${VERSION}")
MESSAGE (STATUS "xPlatAppx branch name ${GIT_BRANCH_NAME}")
MESSAGE (STATUS "MSIX Packaging SDK version ${VERSION}")
MESSAGE (STATUS "MSIX Packaging SDK branch name ${GIT_BRANCH_NAME}")
# Configure Package.nuspec
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Package.nuspec.cmakein ${CMAKE_CURRENT_BINARY_DIR}/Package.nuspec CRLF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Microsoft.xPlat.AppxPackaging.targets ${CMAKE_BINARY_DIR}/build/native/Microsoft.xPlat.AppxPackaging.targets)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Microsoft.MSIX.Packaging.targets ${CMAKE_BINARY_DIR}/build/native/Microsoft.MSIX.Packaging.targets)
MESSAGE (STATUS "Package.Nuspec created")
MESSAGE (STATUS "--------------------------------")
@ -195,7 +195,7 @@ SET(CMAKE_MACOSX_RPATH ON)
add_subdirectory(lib)
MESSAGE (STATUS " ")
MESSAGE (STATUS "--------------------------------")
MESSAGE (STATUS "xPlatAppx")
MESSAGE (STATUS "MSIX Packaging SDK")
MESSAGE (STATUS "--------------------------------")
MESSAGE (STATUS "libs processed")
add_subdirectory(src)

Просмотреть файл

@ -2,8 +2,8 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)..\..\build\native\WIN32\src\xPlatAppx;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_XPLATAPPX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)..\..\build\native\WIN32\src\msix;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAS_MSIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
</Project>

Просмотреть файл

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>Microsoft.xPlat.AppxPackaging</id>
<id>Microsoft.MSIX.Packaging</id>
<version>${VERSION}</version>
<authors>psmith@microsoft.com</authors>
<owners>Xplat-appX@service.microsoft.com</owners>
@ -30,7 +30,7 @@
* 15424167 - Enable iOS build
</releaseNotes>
<copyright>Copyright (C) 2017 Microsoft</copyright>
<tags>xPlatAppx Appx AppxPackaging native</tags>
<tags>MSIX Appx AppxPackaging native</tags>
<dependencies />
</metadata>
</package>

Просмотреть файл

@ -1,11 +1,11 @@
xPlatAppx
MSIX Packaging SDK
---------
Copyright (c) 2017 Microsoft Corp.
All rights reserved.
DESCRIPTION
-----------
The xPlatAppx project is an effort to enable developers on a variety of platforms to package and unpackage
The MSIX Packaging SDK project is an effort to enable developers on a variety of platforms to package and unpackage
application packages for the purposes of distribution from either the Microsoft Windows Apps Store, or
2nd/3rd party stores. To that end, the file format of these packages need to be in a format that is easily
digestible to through the Microsoft Windows Apps Store back-end ingestion processes; which means that the
@ -14,15 +14,14 @@ DESCRIPTION
OVERVIEW
--------
The xPlatAppx project includes:
1. Cross platform API support for unpacakge of .appx package
2. Developer tooling to build .appx package on Windows, MacOS and Linux.
The MSIX Packaging SDK project includes:
1. Cross platform API support for unpacakge of .appx package
The scheduling of the highlevel work listed above will be determined with respect to the relative priorities.
The xPlatAppx project includes:
The MSIX Packaging SDK project includes:
xPlatAppx - A shared library (DLL on Win32, dylib on MacOs, SO on Linux) that exports a subset
msix - A shared library (DLL on Win32, dylib on MacOs, SO on Linux and Android) that exports a subset
of the functionality contained within appxpackaging.dll on Windows. See:
https://msdn.microsoft.com/en-us/library/windows/desktop/hh446766(v=vs.85).aspx
for additional details.
@ -31,12 +30,11 @@ The scheduling of the highlevel work listed above will be determined with respec
CoCreating IAppxFactory, a c-style export: CoCreateAppxFactory is provided instead.
See sample folder at root of package for cross platform consumption examples
Finally, there are two additional exports: 'Pack' and 'Unpack' that provide
simplified package and unpackage implementations respectively.
Finally, there is one exports 'Unpack' that provides an simplified unpackage implementations.
MakeXplatAppx - A command line wrapper over the Pack and Unpack implementations. This tool exists
primarily as a means of validating the implementation of xPlatAppx internal routines
and is compiled for Win32, MacOS, and Linux platforms.
makemsix - A command line wrapper over the Unpack implementation. This tool exists
primarily as a means of validating the implementation of the MSIX Packaging SDK internal
routines and is compiled for Win32, MacOS, and Linux platforms.
SETUP INSTRUCTIONS
------------------
@ -92,9 +90,9 @@ PREREQUISITES
cmake -DCMAKE_ANDROID_NDK=c:/android-ndk ^
-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang ^
-DCMAKE_SYSTEM_NAME=Android ^
-DCMAKE_SYSTEM_VERSION=27 ^
-DCMAKE_SYSTEM_VERSION=19 ^
-DCMAKE_ANDROID_ARCH_ABI=x86 ^
-DCMAKE_ANDROID_STL_TYPE=c++_static ^
-DCMAKE_ANDROID_STL_TYPE=c++_shared ^
-DCMAKE_BUILD_TYPE=Release ^
-DAOSP=on ^
-G"Ninja" ..
@ -123,12 +121,18 @@ BUILD
On Mac using make:
./makemac
./makeios
On Linux using make:
./makelinux
./makeaosp
SUPPORT
-------
TODO: write stuffs here
HOW TO CONTRIBUTE TO xPlatAppx
HOW TO CONTRIBUTE TO MSIX Packaging SDK
------------------------------
TODO: write stuffs here

Просмотреть файл

@ -1,4 +1,4 @@
# xplat\lib
# MSIX\lib
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)

Просмотреть файл

@ -59,8 +59,8 @@ printsetup
mkdir .vs
cd .vs
# clean up any old builds of xPlatAppx modules
find . -name *xPlatAppx* -d | xargs rm -r
# clean up any old builds of msix modules
find . -name *msix* -d | xargs rm -r
cmake -DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_ANDROID_NDK="$ndk" \

Просмотреть файл

@ -37,8 +37,8 @@ printsetup
mkdir .vs
cd .vs
# clean up any old builds of xPlatAppx modules
find . -name *xPlatAppx* -d | xargs rm -r
# clean up any old builds of msix modules
find . -name *msix* -d | xargs rm -r
cmake -DCMAKE_BUILD_TYPE=$build -DIOS=on -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.cmake -DCMAKE_OSX_ARCHITECTURES=$arch ..
make

Просмотреть файл

@ -31,8 +31,8 @@ printsetup
mkdir .vs
cd .vs
# clean up any old builds of xPlatAppx modules
find . -name *xPlatAppx* -d | xargs rm -r
# clean up any old builds of msix modules
find . -name *msix* -d | xargs rm -r
cmake -DCMAKE_BUILD_TYPE=$build -DLINUX=on ..
make

Просмотреть файл

@ -31,8 +31,8 @@ printsetup
mkdir .vs
cd .vs
# clean up any old builds of xPlatAppx modules
find . -name *xPlatAppx* -d | xargs rm -r
# clean up any old builds of msix modules
find . -name *msix* -d | xargs rm -r
cmake -DCMAKE_BUILD_TYPE=$build -DMACOS=on ..
make

Просмотреть файл

@ -1,4 +1,4 @@
# xplat\src
# MSIX\src
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
@ -9,4 +9,4 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
add_subdirectory(ExtractContentsSample)
ADD_DEPENDENCIES(ExtractContentsSample xPlatAppx)
ADD_DEPENDENCIES(ExtractContentsSample msix)

Просмотреть файл

@ -1,9 +1,9 @@
# xplat\src\MakeXplat
# MSIX\src\makemsix
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project (MakeXplat)
project (makemsix)
# Define two variables in order not to repeat ourselves.
set(BINARY_NAME ExtractContentsSample)
@ -20,5 +20,5 @@ add_executable(${BINARY_NAME}
# specify that this binary is to be built with C++14
set_property(TARGET ${BINARY_NAME} PROPERTY CXX_STANDARD 14)
ADD_DEPENDENCIES(${BINARY_NAME} xPlatAppx)
target_link_libraries(${BINARY_NAME} xPlatAppx)
ADD_DEPENDENCIES(${BINARY_NAME} msix)
target_link_libraries(${BINARY_NAME} msix)

Просмотреть файл

@ -20,7 +20,7 @@
#endif
#include "AppxPackaging.hpp"
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
// Stripped down ComPtr provided for those platforms that do not already have a ComPtr class.
template <class T>
@ -92,25 +92,25 @@ struct State
{
bool CreatePackageSubfolder()
{
unpackOptions = static_cast<APPX_PACKUNPACK_OPTION>(unpackOptions | APPX_PACKUNPACK_OPTION::APPX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER);
unpackOptions = static_cast<MSIX_PACKUNPACK_OPTION>(unpackOptions | MSIX_PACKUNPACK_OPTION::MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER);
return true;
}
bool SkipManifestValidation()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPAPPXMANIFEST);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_SKIPAPPXMANIFEST);
return true;
}
bool SkipSignature()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPSIGNATURE);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_SKIPSIGNATURE);
return true;
}
bool AllowSignatureOriginUnknown()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN);
return true;
}
@ -130,8 +130,8 @@ struct State
std::wstring packageName;
std::wstring directoryName;
APPX_VALIDATION_OPTION validationOptions = APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_FULL;
APPX_PACKUNPACK_OPTION unpackOptions = APPX_PACKUNPACK_OPTION::APPX_PACKUNPACK_OPTION_NONE;
MSIX_VALIDATION_OPTION validationOptions = MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL;
MSIX_PACKUNPACK_OPTION unpackOptions = MSIX_PACKUNPACK_OPTION::MSIX_PACKUNPACK_OPTION_NONE;
};
// Displays contextual formatted help to the user.

Просмотреть файл

@ -1,4 +1,4 @@
# xplat\src
# MSIX\src
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
@ -8,10 +8,10 @@ ADD_CUSTOM_TARGET(SRC)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
add_subdirectory(xPlatAppx)
add_subdirectory(MakeXplat)
add_subdirectory(msix)
add_subdirectory(makemsix)
ADD_DEPENDENCIES(MakeXplat xPlatAppx)
ADD_DEPENDENCIES(makemsix msix)
# Create header for BlockMap schemas
@ -22,14 +22,11 @@ file(READ "${CMAKE_PROJECT_ROOT}/certs/base64_Windows_Production.cer" BASE64_WIN
file(READ "${CMAKE_PROJECT_ROOT}/certs/base64_Windows_Production_PCA_2011.cer" BASE64_WINDOWS_PRODUCTION_PCA_2011)
file(READ "${CMAKE_PROJECT_ROOT}/certs/Microsoft_MarketPlace_PCA_2011.cer" BASE64_MSFT_MARKETPLACE_CA_G_016)
# set(PEM_CERTS "${BASE64_MSFT_RCA_2010}${BASE64_MSFT_RCA_2011}${BASE64_WINDOWS_PRODUCTION}${BASE64_WINDOWS_PRODUCTION_PCA_2011}${BASE64_STORE_PCA_2011}")
# file(WRITE "/Users/admin/Documents/foo.pem" "${PEM_CERTS}")
set(APPX_CERTS "// This file is generated by CMake and contains certs for parsing the AppxBlockMap.xml. Do not edit!!
#include <string>
#include <vector>
namespace xPlat {
namespace MSIX {
// Do not alter the order of these certificates -- they are in chain order
std::vector<std::string> appxCerts = {

Просмотреть файл

@ -16,12 +16,12 @@
#include "BlockMapStream.hpp"
#include "xercesc/util/XMLString.hpp"
namespace xPlat {
namespace MSIX {
class AppxBlockMapBlock : public xPlat::ComClass<AppxBlockMapBlock, IAppxBlockMapBlock>
class AppxBlockMapBlock : public MSIX::ComClass<AppxBlockMapBlock, IAppxBlockMapBlock>
{
public:
AppxBlockMapBlock(IxPlatFactory* factory, Block* block) :
AppxBlockMapBlock(IMSIXFactory* factory, Block* block) :
m_factory(factory),
m_block(block)
{}
@ -43,11 +43,11 @@ namespace xPlat {
}
private:
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
Block* m_block;
};
class AppxBlockMapBlocksEnumerator : public xPlat::ComClass<AppxBlockMapBlocksEnumerator, IAppxBlockMapBlocksEnumerator>
class AppxBlockMapBlocksEnumerator : public MSIX::ComClass<AppxBlockMapBlocksEnumerator, IAppxBlockMapBlocksEnumerator>
{
protected:
std::vector<ComPtr<IAppxBlockMapBlock>>* m_blocks;
@ -83,11 +83,11 @@ namespace xPlat {
}
};
class AppxBlockMapFile : public xPlat::ComClass<AppxBlockMapFile, IAppxBlockMapFile>
class AppxBlockMapFile : public MSIX::ComClass<AppxBlockMapFile, IAppxBlockMapFile>
{
public:
AppxBlockMapFile(
IxPlatFactory* factory,
IMSIXFactory* factory,
std::vector<Block>* blocks,
std::uint32_t localFileHeaderSize,
const std::string& name,
@ -156,13 +156,13 @@ namespace xPlat {
std::vector<ComPtr<IAppxBlockMapBlock>> m_blockMapBlocks;
std::vector<Block>* m_blocks;
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
std::uint32_t m_localFileHeaderSize;
std::string m_name;
std::uint64_t m_uncompressedSize;
};
class AppxBlockMapFilesEnumerator : public xPlat::ComClass<AppxBlockMapFilesEnumerator, IAppxBlockMapFilesEnumerator>
class AppxBlockMapFilesEnumerator : public MSIX::ComClass<AppxBlockMapFilesEnumerator, IAppxBlockMapFilesEnumerator>
{
protected:
ComPtr<IAppxBlockMapReader> m_reader;
@ -200,16 +200,16 @@ namespace xPlat {
};
// Object backed by AppxBlockMap.xml
class AppxBlockMapObject : public xPlat::ComClass<AppxBlockMapObject, IAppxBlockMapReader, IVerifierObject, IStorageObject>
class AppxBlockMapObject : public MSIX::ComClass<AppxBlockMapObject, IAppxBlockMapReader, IVerifierObject, IStorageObject>
{
public:
AppxBlockMapObject(IxPlatFactory* factory, ComPtr<IStream>& stream);
AppxBlockMapObject(IMSIXFactory* factory, ComPtr<IStream>& stream);
// IVerifierObject
const std::string& GetPublisher() override { throw Exception(Error::NotSupported); }
bool HasStream() override { return m_stream.Get() != nullptr; }
xPlat::ComPtr<IStream> GetStream() override { return m_stream; }
xPlat::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override;
MSIX::ComPtr<IStream> GetStream() override { return m_stream; }
MSIX::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override;
// IAppxBlockMapReader
HRESULT STDMETHODCALLTYPE GetFile(LPCWSTR filename, IAppxBlockMapFile **file) override;
@ -222,13 +222,13 @@ namespace xPlat {
std::vector<std::string> GetFileNames(FileNameOptions options) override;
IStream* GetFile(const std::string& fileName) override;
void RemoveFile(const std::string& fileName) override;
IStream* OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode) override;
IStream* OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode) override;
void CommitChanges() override;
protected:
std::map<std::string, std::vector<Block>> m_blockMap;
std::map<std::string, ComPtr<IAppxBlockMapFile>> m_blockMapfiles;
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
ComPtr<IStream> m_stream;
};
}

Просмотреть файл

@ -1,7 +1,7 @@
#pragma once
#include "AppxPackaging.hpp"
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "ComHelper.hpp"
#include "xercesc/util/PlatformUtils.hpp"
@ -9,29 +9,29 @@
#include <vector>
// internal interface
EXTERN_C const IID IID_IxPlatFactory;
EXTERN_C const IID IID_IMSIXFactory;
#ifndef WIN32
// {1f850db4-32b8-4db6-8bf4-5a897eb611f1}
interface IxPlatFactory : public IUnknown
interface IMSIXFactory : public IUnknown
#else
#include "UnKnwn.h"
#include "Objidl.h"
class IxPlatFactory : public IUnknown
class IMSIXFactory : public IUnknown
#endif
{
public:
virtual HRESULT MarshalOutString(std::string& internal, LPWSTR *result) = 0;
virtual HRESULT MarshalOutBytes(std::vector<std::uint8_t>& data, UINT32* size, BYTE** buffer) = 0;
virtual APPX_VALIDATION_OPTION GetValidationOptions() = 0;
virtual MSIX_VALIDATION_OPTION GetValidationOptions() = 0;
};
SpecializeUuidOfImpl(IxPlatFactory);
SpecializeUuidOfImpl(IMSIXFactory);
namespace xPlat {
class AppxFactory : public ComClass<AppxFactory, IxPlatFactory, IAppxFactory>
namespace MSIX {
class AppxFactory : public ComClass<AppxFactory, IMSIXFactory, IAppxFactory>
{
public:
AppxFactory(APPX_VALIDATION_OPTION validationOptions, COTASKMEMALLOC* memalloc, COTASKMEMFREE* memfree ) :
AppxFactory(MSIX_VALIDATION_OPTION validationOptions, COTASKMEMALLOC* memalloc, COTASKMEMFREE* memfree ) :
m_validationOptions(validationOptions), m_memalloc(memalloc), m_memfree(memfree)
{
ThrowErrorIf(Error::InvalidParameter, (m_memalloc == nullptr || m_memfree == nullptr), "allocator/deallocator pair not specified.")
@ -58,13 +58,13 @@ namespace xPlat {
LPCWSTR signatureFileName,
IAppxBlockMapReader** blockMapReader) override;
// IxPlatFactory
// IMSIXFactory
HRESULT MarshalOutString(std::string& internal, LPWSTR *result) override;
HRESULT MarshalOutBytes(std::vector<std::uint8_t>& data, UINT32* size, BYTE** buffer) override;
APPX_VALIDATION_OPTION GetValidationOptions() override { return m_validationOptions; }
MSIX_VALIDATION_OPTION GetValidationOptions() override { return m_validationOptions; }
COTASKMEMALLOC* m_memalloc;
COTASKMEMFREE* m_memfree;
APPX_VALIDATION_OPTION m_validationOptions;
MSIX_VALIDATION_OPTION m_validationOptions;
};
}

Просмотреть файл

@ -6,7 +6,7 @@
#include <memory>
#include "AppxPackaging.hpp"
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "Exceptions.hpp"
#include "ComHelper.hpp"
#include "StreamBase.hpp"
@ -19,25 +19,24 @@
#include "AppxFactory.hpp"
// internal interface
EXTERN_C const IID IID_IAppxPackage;
EXTERN_C const IID IID_IPackage;
#ifndef WIN32
// {51b2c456-aaa9-46d6-8ec9-298220559189}
interface IAppxPackage : public IUnknown
interface IPackage : public IUnknown
#else
#include "Unknwn.h"
#include "Objidl.h"
class IAppxPackage : public IUnknown
class IPackage : public IUnknown
#endif
{
public:
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 void Unpack(MSIX_PACKUNPACK_OPTION options, IStorageObject* to) = 0;
virtual std::vector<std::string>& GetFootprintFiles() = 0;
};
SpecializeUuidOfImpl(IAppxPackage);
SpecializeUuidOfImpl(IPackage);
namespace xPlat {
namespace MSIX {
// The 5-tuple that describes the identity of a package
struct AppxPackageId
{
@ -75,8 +74,8 @@ namespace xPlat {
// IVerifierObject
const std::string& GetPublisher() override { return GetPackageId()->Publisher; }
bool HasStream() override { return m_stream.Get() != nullptr; }
xPlat::ComPtr<IStream> GetStream() override { return m_stream; }
xPlat::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override
MSIX::ComPtr<IStream> GetStream() override { return m_stream; }
MSIX::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override
{
throw Exception(Error::NotSupported);
}
@ -90,15 +89,14 @@ namespace xPlat {
};
// Storage object representing the entire AppxPackage
class AppxPackageObject : public ComClass<AppxPackageObject, IAppxPackageReader, IAppxPackage, IStorageObject>
class AppxPackageObject : public ComClass<AppxPackageObject, IAppxPackageReader, IPackage, IStorageObject>
{
public:
AppxPackageObject(IxPlatFactory* factory, APPX_VALIDATION_OPTION validation, IStorageObject* container);
AppxPackageObject(IMSIXFactory* factory, MSIX_VALIDATION_OPTION validation, IStorageObject* container);
~AppxPackageObject() {}
// internal IxPlatAppxPackage methods
void Pack(APPX_PACKUNPACK_OPTION options, const std::string& certFile, IStorageObject* from) override;
void Unpack(APPX_PACKUNPACK_OPTION options, IStorageObject* to) override;
// internal IPackage methods
void Unpack(MSIX_PACKUNPACK_OPTION options, IStorageObject* to) override;
// IAppxPackageReader
HRESULT STDMETHODCALLTYPE GetBlockMap(IAppxBlockMapReader** blockMapReader) override;
@ -107,7 +105,7 @@ namespace xPlat {
HRESULT STDMETHODCALLTYPE GetPayloadFiles(IAppxFilesEnumerator** filesEnumerator) override;
HRESULT STDMETHODCALLTYPE GetManifest(IAppxManifestReader** manifestReader) override;
// returns a list of the footprint files found within this appx package.
// returns a list of the footprint files found within this package.
std::vector<std::string>& GetFootprintFiles() override { return m_footprintFiles; }
// IStorageObject methods
@ -115,14 +113,14 @@ namespace xPlat {
std::vector<std::string> GetFileNames(FileNameOptions options) override;
IStream* GetFile(const std::string& fileName) override;
void RemoveFile(const std::string& fileName) override;
IStream* OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode) override;
IStream* OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode) override;
void CommitChanges() override;
protected:
std::map<std::string, ComPtr<IStream>> m_streams;
APPX_VALIDATION_OPTION m_validation = APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_FULL;
ComPtr<IxPlatFactory> m_factory;
MSIX_VALIDATION_OPTION m_validation = MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL;
ComPtr<IMSIXFactory> m_factory;
ComPtr<IVerifierObject> m_appxSignature;
ComPtr<IVerifierObject> m_appxBlockMap;
ComPtr<IVerifierObject> m_appxManifest;
@ -133,7 +131,7 @@ namespace xPlat {
std::vector<std::string> m_footprintFiles;
};
class AppxFilesEnumerator : public xPlat::ComClass<AppxFilesEnumerator, IAppxFilesEnumerator>
class AppxFilesEnumerator : public MSIX::ComClass<AppxFilesEnumerator, IAppxFilesEnumerator>
{
protected:
ComPtr<IStorageObject> m_storage;

Просмотреть файл

@ -6,13 +6,13 @@
// - Remove C style interfaces declaration
// - Remove MIDL_INTERFACE MACRO
// - Add IUnknown, ISequentialStream and IStream interfaces
// - Add xPlatAppx specific funcions and helpers (See bottom of file)
// - Add MSIX specific funcions and helpers (See bottom of file)
// - See more changes in AppxPackaging_i.cpp
#ifndef __appxpackaging_hpp__
#define __appxpackaging_hpp__
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#ifdef WIN32
#include <AppxPackaging.h>
@ -1986,28 +1986,28 @@ EXTERN_C const IID IID_IAppxEncryptedBundleWriter2;
} // extern "C"
#endif // #ifdef WIN32
// MSIX specific
extern "C++" {
typedef /* [v1_enum] */
enum APPX_VALIDATION_OPTION
enum MSIX_VALIDATION_OPTION
{
APPX_VALIDATION_OPTION_FULL = 0x0,
APPX_VALIDATION_OPTION_SKIPSIGNATURE = 0x1,
APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN = 0x2,
APPX_VALIDATION_OPTION_SKIPAPPXMANIFEST = 0x4
} APPX_VALIDATION_OPTION;
MSIX_VALIDATION_OPTION_FULL = 0x0,
MSIX_VALIDATION_OPTION_SKIPSIGNATURE = 0x1,
MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN = 0x2,
MSIX_VALIDATION_OPTION_SKIPAPPXMANIFEST = 0x4
} MSIX_VALIDATION_OPTION;
typedef /* [v1_enum] */
enum APPX_PACKUNPACK_OPTION
enum MSIX_PACKUNPACK_OPTION
{
APPX_PACKUNPACK_OPTION_NONE = 0x0,
APPX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER = 0x1
} APPX_PACKUNPACK_OPTION;
MSIX_PACKUNPACK_OPTION_NONE = 0x0,
MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER = 0x1
} MSIX_PACKUNPACK_OPTION;
// xPlatAppx specific
XPLATAPPX_API HRESULT STDMETHODCALLTYPE UnpackAppx(
APPX_PACKUNPACK_OPTION packUnpackOptions,
APPX_VALIDATION_OPTION validationOption,
MSIX_API HRESULT STDMETHODCALLTYPE UnpackPackage(
MSIX_PACKUNPACK_OPTION packUnpackOptions,
MSIX_VALIDATION_OPTION validationOption,
char* utf8SourcePackage,
char* utf8Destination
);
@ -2017,26 +2017,26 @@ XPLATAPPX_API HRESULT STDMETHODCALLTYPE UnpackAppx(
typedef LPVOID STDMETHODCALLTYPE COTASKMEMALLOC(SIZE_T cb);
typedef void STDMETHODCALLTYPE COTASKMEMFREE(LPVOID pv);
XPLATAPPX_API HRESULT STDMETHODCALLTYPE GetLogTextUTF8(COTASKMEMALLOC* memalloc, char** logText);
MSIX_API HRESULT STDMETHODCALLTYPE GetLogTextUTF8(COTASKMEMALLOC* memalloc, char** logText);
// Call specific for Windows. Default to call CoTaskMemAlloc and CoTaskMemFree
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
APPX_VALIDATION_OPTION validationOption,
MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
MSIX_VALIDATION_OPTION validationOption,
IAppxFactory** appxFactory);
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactoryWithHeap(
MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactoryWithHeap(
COTASKMEMALLOC* memalloc,
COTASKMEMFREE* memfree,
APPX_VALIDATION_OPTION validationOption,
MSIX_VALIDATION_OPTION validationOption,
IAppxFactory** appxFactory);
// provided as a helper for platforms that do not have an implementation of SHCreateStreamOnFileEx
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFile(
MSIX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFile(
char* utf8File,
bool forRead,
IStream** stream);
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFileUTF16(
MSIX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFileUTF16(
LPCWSTR utf16File,
bool forRead,
IStream** stream);

Просмотреть файл

@ -7,7 +7,7 @@
#include <vector>
#include <map>
namespace xPlat {
namespace MSIX {
enum class SignatureOrigin
{
@ -48,13 +48,13 @@ namespace xPlat {
AXCI = 0x49435841, // AppxMetadata/CodeIntegrity.cat (uncompressed, optional)
};
AppxSignatureObject(APPX_VALIDATION_OPTION validationOptions, IStream* stream);
AppxSignatureObject(MSIX_VALIDATION_OPTION validationOptions, IStream* stream);
// IVerifierObject
const std::string& GetPublisher() override { return m_publisher; }
bool HasStream() override { return m_stream.Get() != nullptr; }
xPlat::ComPtr<IStream> GetStream() override { return m_stream; }
xPlat::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override;
MSIX::ComPtr<IStream> GetStream() override { return m_stream; }
MSIX::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override;
using Digest = std::vector<std::uint8_t>;
@ -69,8 +69,8 @@ namespace xPlat {
bool m_hasDigests;
std::map<DigestName, Digest> m_digests;
SignatureOrigin m_signatureOrigin = SignatureOrigin::Unsigned; // assume unsigned until proven otherwise.
APPX_VALIDATION_OPTION m_validationOptions;
MSIX_VALIDATION_OPTION m_validationOptions;
ComPtr<IStream> m_stream;
std::string m_publisher;
};
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -1,6 +1,6 @@
#pragma once
#define NOMINMAX /* windows.h, or more correctly windef.h, defines min as a macro... */
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "Exceptions.hpp"
#include "StreamBase.hpp"
#include "RangeStream.hpp"
@ -15,7 +15,7 @@
#include <algorithm>
#include <vector>
namespace xPlat {
namespace MSIX {
const std::uint64_t BLOCKMAP_BLOCK_SIZE = 65536; // 64KB
@ -36,7 +36,7 @@ namespace xPlat {
class BlockMapStream : public StreamBase
{
public:
BlockMapStream(IxPlatFactory* factory, std::string decodedName, IStream* stream, std::vector<Block>& blocks)
BlockMapStream(IMSIXFactory* factory, std::string decodedName, IStream* stream, std::vector<Block>& blocks)
: m_factory(factory), m_decodedName(decodedName), m_stream(stream)
{
// Determine overall stream size
@ -163,6 +163,6 @@ namespace xPlat {
std::uint64_t m_streamSize;
std::string m_decodedName;
ComPtr<IStream> m_stream;
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
};
}

Просмотреть файл

@ -9,7 +9,7 @@
#include "AppxPackaging.hpp"
#include "xercesc/util/XMLString.hpp"
namespace xPlat {
namespace MSIX {
template <typename ...Interfaces>
struct QIHelper;
@ -160,7 +160,7 @@ namespace xPlat {
AddRef();
return S_OK;
}
throw xPlat::Exception(xPlat::Error::NoInterface);
throw MSIX::Exception(MSIX::Error::NoInterface);
});
}

Просмотреть файл

@ -10,7 +10,7 @@
#include "StorageObject.hpp"
#include "ComHelper.hpp"
namespace xPlat {
namespace MSIX {
class DirectoryObject : public ComClass<DirectoryObject, IStorageObject>
{
@ -22,7 +22,7 @@ namespace xPlat {
std::vector<std::string> GetFileNames(FileNameOptions options) override;
IStream* GetFile(const std::string& fileName) override;
void RemoveFile(const std::string& fileName) override;
IStream* OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode) override;
IStream* OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode) override;
void CommitChanges() override;
protected:

Просмотреть файл

@ -7,13 +7,13 @@
#include <functional>
#include "Log.hpp"
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "xercesc/util/PlatformUtils.hpp"
#include "xercesc/sax/ErrorHandler.hpp"
#include "xercesc/sax/SAXParseException.hpp"
#include "xercesc/dom/DOM.hpp"
namespace xPlat {
namespace MSIX {
static const std::uint32_t ERROR_FACILITY = 0x8BAD0000; // Facility 2989
static const std::uint32_t XERCES_SAX_FACILITY = ERROR_FACILITY + 0x1000; // Xerces XMLException. 0x8BAD1000 + XMLException error code
@ -37,7 +37,7 @@ namespace xPlat {
Stg_E_Invalidpointer = 0x80030009,
//
// xPlat specific error codes
// msix specific error codes
//
// Basic file errors
@ -62,18 +62,18 @@ namespace xPlat {
InflateRead = ERROR_FACILITY + 0x0022,
InflateCorruptData = ERROR_FACILITY + 0x0023,
// AppxPackage format errors
AppxMissingSignatureP7X = ERROR_FACILITY + 0x0031,
AppxMissingContentTypesXML = ERROR_FACILITY + 0x0032,
AppxMissingBlockMapXML = ERROR_FACILITY + 0x0033,
AppxMissingAppxManifestXML = ERROR_FACILITY + 0x0034,
AppxDuplicateFootprintFile = ERROR_FACILITY + 0x0035,
AppxUnknownFileNameEncoding = ERROR_FACILITY + 0x0036,
// Package format errors
MissingAppxSignatureP7X = ERROR_FACILITY + 0x0031,
MissingContentTypesXML = ERROR_FACILITY + 0x0032,
MissingAppxBlockMapXML = ERROR_FACILITY + 0x0033,
MissingAppxManifestXML = ERROR_FACILITY + 0x0034,
DuplicateFootprintFile = ERROR_FACILITY + 0x0035,
UnknownFileNameEncoding = ERROR_FACILITY + 0x0036,
// Signature errors
AppxSignatureInvalid = ERROR_FACILITY + 0x0041,
AppxCertNotTrusted = ERROR_FACILITY + 0x0042,
AppxPublisherMismatch = ERROR_FACILITY + 0x0043,
SignatureInvalid = ERROR_FACILITY + 0x0041,
CertNotTrusted = ERROR_FACILITY + 0x0042,
PublisherMismatch = ERROR_FACILITY + 0x0043,
// Blockmap semantic errors
BlockMapSemanticError = ERROR_FACILITY + 0x0051,
@ -88,7 +88,7 @@ namespace xPlat {
};
// Defines a common exception type to throw in exceptional cases. DO NOT USE FOR FLOW CONTROL!
// Throwing xPlat::Exception will break into the debugger on chk builds to aid debugging
// Throwing MSIX::Exception will break into the debugger on chk builds to aid debugging
class Exception : public std::exception
{
public:
@ -176,21 +176,21 @@ namespace xPlat {
{
// TODO: add message, line number and column
assert(false);
throw Exception(xPlat::Error::XercesWarning);
throw Exception(MSIX::Error::XercesWarning);
}
void error(const XERCES_CPP_NAMESPACE::SAXParseException& exp) override
{
// TODO: add message, line number and column
assert(false);
throw Exception(xPlat::Error::XercesError);
throw Exception(MSIX::Error::XercesError);
}
void fatalError(const XERCES_CPP_NAMESPACE::SAXParseException& exp) override
{
// TODO: add message, line number and column
assert(false);
throw Exception(xPlat::Error::XercesFatal);
throw Exception(MSIX::Error::XercesFatal);
}
void resetErrors() override {}
@ -200,31 +200,31 @@ namespace xPlat {
template <class Lambda>
inline HRESULT ResultOf(Lambda lambda)
{
HRESULT hr = static_cast<HRESULT>(xPlat::Error::OK);
HRESULT hr = static_cast<HRESULT>(MSIX::Error::OK);
try
{
lambda();
}
catch (xPlat::Exception& e)
catch (MSIX::Exception& e)
{
hr = static_cast<HRESULT>(e.Code());
}
catch (std::bad_alloc&)
{
hr = static_cast<HRESULT>(xPlat::Error::OutOfMemory);
hr = static_cast<HRESULT>(MSIX::Error::OutOfMemory);
}
catch (std::exception&)
{
hr = static_cast<HRESULT>(xPlat::Error::Unexpected);
hr = static_cast<HRESULT>(MSIX::Error::Unexpected);
}
catch (const XERCES_CPP_NAMESPACE::XMLException& e)
{
hr = static_cast<HRESULT>(xPlat::XERCES_XML_FACILITY) +
hr = static_cast<HRESULT>(MSIX::XERCES_XML_FACILITY) +
static_cast<HRESULT>(e.getCode());
}
catch (const XERCES_CPP_NAMESPACE::DOMException& e)
{
hr = static_cast<HRESULT>(xPlat::XERCES_DOM_FACILITY) +
hr = static_cast<HRESULT>(MSIX::XERCES_DOM_FACILITY) +
static_cast<HRESULT>(e.code);
}
@ -238,7 +238,7 @@ namespace xPlat {
if (!(a)) \
{ \
assert(false); \
throw xPlat::Exception(c,m); \
throw MSIX::Exception(c,m); \
} \
}
@ -247,7 +247,7 @@ namespace xPlat {
if (!(a)) \
{ \
assert(false); \
throw xPlat::Win32Exception(c,m); \
throw MSIX::Win32Exception(c,m); \
} \
}
@ -258,6 +258,6 @@ namespace xPlat {
HRESULT hr = a; \
if (FAILED(hr)) \
{ assert(false); \
throw xPlat::Exception(hr, "COM Call failed"); \
throw MSIX::Exception(hr, "COM Call failed"); \
} \
}

Просмотреть файл

@ -7,7 +7,7 @@
#include "Exceptions.hpp"
#include "StreamBase.hpp"
namespace xPlat {
namespace MSIX {
class FileStream : public StreamBase
{
public:

Просмотреть файл

@ -1,6 +1,6 @@
#pragma once
#define NOMINMAX /* windows.h, or more correctly windef.h, defines min as a macro... */
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "Exceptions.hpp"
#include "StreamBase.hpp"
#include "ComHelper.hpp"
@ -11,7 +11,7 @@
#include <functional>
#include <algorithm>
namespace xPlat {
namespace MSIX {
// This represents a subset of a Stream
class HashStream : public StreamBase
@ -49,16 +49,16 @@ namespace xPlat {
m_cacheBuffer = std::make_unique<std::vector<std::uint8_t>>(m_streamSize);
ULONG bytesRead = 0;
ThrowHrIfFailed(m_stream->Read(m_cacheBuffer->data(), m_cacheBuffer->size(), &bytesRead));
ThrowErrorIfNot(xPlat::Error::AppxSignatureInvalid, bytesRead == m_streamSize, "read failed");
ThrowErrorIfNot(MSIX::Error::SignatureInvalid, bytesRead == m_streamSize, "read failed");
// compute digest and compare against expected digest
std::vector<std::uint8_t> hash;
ThrowErrorIfNot(xPlat::Error::AppxSignatureInvalid,
xPlat::SHA256::ComputeHash(m_cacheBuffer->data(), m_cacheBuffer->size(), hash),
ThrowErrorIfNot(MSIX::Error::SignatureInvalid,
MSIX::SHA256::ComputeHash(m_cacheBuffer->data(), m_cacheBuffer->size(), hash),
"Invalid signature");
ThrowErrorIfNot(xPlat::Error::AppxSignatureInvalid, m_expectedHash.size() == hash.size(), "Signature is corrupt");
ThrowErrorIfNot(MSIX::Error::SignatureInvalid, m_expectedHash.size() == hash.size(), "Signature is corrupt");
ThrowErrorIfNot(
xPlat::Error::AppxSignatureInvalid,
MSIX::Error::SignatureInvalid,
memcmp(m_expectedHash.data(), hash.data(), hash.size()) == 0,
"Signature hash doesn't match digest hash"); //TODO: better exception

Просмотреть файл

@ -16,7 +16,7 @@
#include <map>
#include <functional>
namespace xPlat {
namespace MSIX {
// This represents a LZW-compressed stream
class InflateStream : public StreamBase

Просмотреть файл

@ -1,7 +1,7 @@
#pragma once
#include <string>
namespace xPlat {
namespace MSIX {
namespace Global {
namespace Log {
void Append(const std::string& comment);

Просмотреть файл

@ -8,7 +8,7 @@
#ifdef WIN32
#define STDMETHODCALLTYPE __stdcall
#define XPLATAPPX_API extern "C" __declspec(dllexport)
#define MSIX_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
@ -29,8 +29,8 @@
#define STDMETHODCALLTYPE
#endif
#undef XPLATAPPX_API
#define XPLATAPPX_API extern "C"
#undef MSIX_API
#define MSIX_API extern "C"
#ifndef interface
#define interface struct

Просмотреть файл

@ -10,7 +10,7 @@
#include "Exceptions.hpp"
#include "StreamBase.hpp"
namespace xPlat {
namespace MSIX {
namespace Meta {
// Represents a heterogeneous collection of types that can be operated on as a compile-time vector

Просмотреть файл

@ -8,7 +8,7 @@
#include <functional>
namespace xPlat {
namespace MSIX {
// This represents a subset of a Stream
class RangeStream : public StreamBase

Просмотреть файл

@ -2,7 +2,7 @@
#include <vector>
namespace xPlat {
namespace MSIX {
const unsigned HASH_BYTES = 32;

Просмотреть файл

@ -6,17 +6,17 @@
#include <vector>
#include <map>
namespace xPlat {
namespace MSIX {
typedef struct DigestHash
{
xPlat::AppxSignatureObject::DigestName name;
MSIX::AppxSignatureObject::DigestName name;
std::uint8_t content[HASH_BYTES];
} DigestHash;
typedef struct DigestHeader
{
xPlat::AppxSignatureObject::DigestName name;
MSIX::AppxSignatureObject::DigestName name;
DigestHash hash[1];
} DigestHeader;
@ -24,11 +24,11 @@ namespace xPlat {
{
public:
static bool Validate(
/*in*/ APPX_VALIDATION_OPTION option,
/*in*/ IStream *stream,
/*inout*/ std::map<xPlat::AppxSignatureObject::DigestName, xPlat::AppxSignatureObject::Digest>& digests,
/*inout*/ SignatureOrigin& origin,
/*inout*/ std::string& publisher);
MSIX_VALIDATION_OPTION option,
IStream *stream,
std::map<MSIX::AppxSignatureObject::DigestName, MSIX::AppxSignatureObject::Digest>& digests,
SignatureOrigin& origin,
std::string& publisher);
};
}

Просмотреть файл

@ -52,7 +52,7 @@ public:
// Opens a stream to a file by name in the storage object. If the file does not exist and mode is read,
// or read + update, then nullptr is returned. If the file is opened with write and it does not exist,
// then the file is created and an empty stream to the file is handed back to the caller.
virtual IStream* OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode) = 0;
virtual IStream* OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode) = 0;
// Some storage objects may operate under cache semantics and therefore require an explicit commit.
// Clients should explicitly call CommitChanges after all write operations into the object are complete.

Просмотреть файл

@ -6,13 +6,13 @@
#include <iostream>
#include <limits>
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "AppxPackaging.hpp"
#include "Exceptions.hpp"
#include "ComHelper.hpp"
namespace xPlat {
class StreamBase : public xPlat::ComClass<StreamBase, IAppxFile, IStream>
namespace MSIX {
class StreamBase : public MSIX::ComClass<StreamBase, IAppxFile, IStream>
{
public:
// These are the same values as STREAM_SEEK. See

Просмотреть файл

@ -2,7 +2,7 @@
#include <string>
namespace xPlat {
namespace MSIX {
// converts an input utf8 formatted string into a utf16 formatted string
std::wstring utf8_to_utf16(const std::string& utf8string);
@ -10,4 +10,4 @@ namespace xPlat {
// converts an input utf16 formatted string into a utf8 formatted string
std::string utf16_to_utf8(const std::wstring& utf16string);
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -5,7 +5,7 @@
#include <vector>
#include <algorithm>
namespace xPlat {
namespace MSIX {
class VectorStream : public StreamBase
{
@ -47,4 +47,4 @@ namespace xPlat {
ULONG m_offset = 0;
std::vector<std::uint8_t>* m_data;
};
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -21,8 +21,8 @@ class IVerifierObject : public IUnknown
public:
virtual const std::string& GetPublisher() = 0;
virtual bool HasStream() = 0;
virtual xPlat::ComPtr<IStream> GetStream() = 0;
virtual xPlat::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) = 0;
virtual MSIX::ComPtr<IStream> GetStream() = 0;
virtual MSIX::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) = 0;
};
SpecializeUuidOfImpl(IVerifierObject);

Просмотреть файл

@ -35,7 +35,7 @@ public:
SpecializeUuidOfImpl(IXmlObject);
namespace xPlat {
namespace MSIX {
// XML de-serialization happens during construction, of this object.
// XML serialization happens through the Write method
@ -108,8 +108,8 @@ namespace xPlat {
// IVerifierObject
const std::string& GetPublisher() override { throw Exception(Error::NotSupported); }
bool HasStream() override { return m_stream.Get() != nullptr; }
xPlat::ComPtr<IStream> GetStream() override { return m_stream; }
xPlat::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override
MSIX::ComPtr<IStream> GetStream() override { return m_stream; }
MSIX::ComPtr<IStream> GetValidationStream(const std::string& part, IStream* stream) override
{
throw Exception(Error::NotSupported);
}
@ -119,4 +119,4 @@ namespace xPlat {
ComPtr<IStream> m_stream;
};
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -7,7 +7,7 @@
#include <string>
namespace xPlat {
namespace MSIX {
// This represents a raw stream over a file contained in a .zip file.
class ZipFileStream : public RangeStream
@ -17,7 +17,7 @@ namespace xPlat {
ZipFileStream(
std::string name,
std::string contentType,
IxPlatFactory* factory,
IMSIXFactory* factory,
bool isCompressed,
std::uint64_t offset,
std::uint64_t size,
@ -45,7 +45,7 @@ namespace xPlat {
inline bool IsCompressed() { return m_isCompressed; }
protected:
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
std::string m_name;
std::string m_contentType;
bool m_isCompressed = false;

Просмотреть файл

@ -10,23 +10,23 @@
#include <map>
#include <memory>
namespace xPlat {
namespace MSIX {
// This represents a raw stream over a.zip file.
class ZipObject : public ComClass<ZipObject, IStorageObject>
{
public:
ZipObject(IxPlatFactory* appxFactory, IStream* stream);
ZipObject(IMSIXFactory* factory, IStream* stream);
// StorageObject methods
std::string GetPathSeparator() override;
std::vector<std::string> GetFileNames(FileNameOptions options) override;
IStream* GetFile(const std::string& fileName) override;
void RemoveFile(const std::string& fileName) override;
IStream* OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode) override;
IStream* OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode) override;
void CommitChanges() override;
protected:
IxPlatFactory* m_factory;
IMSIXFactory* m_factory;
ComPtr<IStream> m_stream;
std::map<std::string, ComPtr<IStream>> m_streams;
};//class ZipObject

Просмотреть файл

@ -1,13 +1,13 @@
# xplat\src\MakeXplat
# MSIX\src\makemsix
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project (MakeXplat)
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project (makemsix)
# Define two variables in order not to repeat ourselves.
set(BINARY_NAME MakeXplat)
set(BINARY_NAME makemsix)
include_directories(
${include_directories}
${CMAKE_PROJECT_ROOT}/src/inc
@ -16,9 +16,9 @@ include_directories(
add_executable(${BINARY_NAME}
main.cpp
)
# specify that this binary is to be built with C++14
# specify that this binary is to be built with C++14
set_property(TARGET ${BINARY_NAME} PROPERTY CXX_STANDARD 14)
ADD_DEPENDENCIES(${BINARY_NAME} xPlatAppx)
target_link_libraries(${BINARY_NAME} xPlatAppx)
ADD_DEPENDENCIES(${BINARY_NAME} msix)
target_link_libraries(${BINARY_NAME} msix)

Просмотреть файл

@ -1,4 +1,4 @@
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "AppxPackaging.hpp"
#include <iostream>
@ -33,25 +33,25 @@ struct State
bool CreatePackageSubfolder()
{
unpackOptions = static_cast<APPX_PACKUNPACK_OPTION>(unpackOptions | APPX_PACKUNPACK_OPTION::APPX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER);
unpackOptions = static_cast<MSIX_PACKUNPACK_OPTION>(unpackOptions | MSIX_PACKUNPACK_OPTION::MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER);
return true;
}
bool SkipManifestValidation()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPAPPXMANIFEST);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_SKIPAPPXMANIFEST);
return true;
}
bool SkipSignature()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPSIGNATURE);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_SKIPSIGNATURE);
return true;
}
bool AllowSignatureOriginUnknown()
{
validationOptions = static_cast<APPX_VALIDATION_OPTION>(validationOptions | APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN);
validationOptions = static_cast<MSIX_VALIDATION_OPTION>(validationOptions | MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN);
return true;
}
@ -73,8 +73,8 @@ struct State
std::string certName;
std::string directoryName;
UserSpecified specified = UserSpecified::Nothing;
APPX_VALIDATION_OPTION validationOptions = APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_FULL;
APPX_PACKUNPACK_OPTION unpackOptions = APPX_PACKUNPACK_OPTION::APPX_PACKUNPACK_OPTION_NONE;
MSIX_VALIDATION_OPTION validationOptions = MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_FULL;
MSIX_PACKUNPACK_OPTION unpackOptions = MSIX_PACKUNPACK_OPTION::MSIX_PACKUNPACK_OPTION_NONE;
};
// describes an option to a command that the user may specify
@ -205,7 +205,7 @@ int ParseAndRun(std::map<std::string, Command>& commands, State& state, int argc
Error(argv[0]);
return -1;
}
return UnpackAppx(state.unpackOptions, state.validationOptions,
return UnpackPackage(state.unpackOptions, state.validationOptions,
const_cast<char*>(state.packageName.c_str()),
const_cast<char*>(state.directoryName.c_str())
);

Просмотреть файл

@ -28,7 +28,7 @@
XERCES_CPP_NAMESPACE_USE
namespace xPlat {
namespace MSIX {
static std::uint32_t GetLocalFileHeaderSize(XERCES_CPP_NAMESPACE::DOMElement* element)
{
@ -82,7 +82,7 @@ namespace xPlat {
return result;
}
AppxBlockMapObject::AppxBlockMapObject(IxPlatFactory* factory, ComPtr<IStream>& stream) : m_factory(factory), m_stream(stream)
AppxBlockMapObject::AppxBlockMapObject(IMSIXFactory* factory, ComPtr<IStream>& stream) : m_factory(factory), m_stream(stream)
{
auto dom = ComPtr<IXmlObject>::Make<XmlObject>(stream, &blockMapSchema);
// Create xPath query over blockmap file.
@ -135,7 +135,7 @@ namespace xPlat {
}
}
xPlat::ComPtr<IStream> AppxBlockMapObject::GetValidationStream(const std::string& part, IStream* stream)
MSIX::ComPtr<IStream> AppxBlockMapObject::GetValidationStream(const std::string& part, IStream* stream)
{
ThrowErrorIf(Error::InvalidParameter, (part.empty() || stream == nullptr), "bad input");
auto item = m_blockMap.find(part);
@ -207,6 +207,6 @@ namespace xPlat {
}
void AppxBlockMapObject::RemoveFile(const std::string& ) { throw Exception(Error::NotImplemented); }
IStream* AppxBlockMapObject::OpenFile(const std::string& ,xPlat::FileStream::Mode) { throw Exception(Error::NotImplemented); }
IStream* AppxBlockMapObject::OpenFile(const std::string& ,MSIX::FileStream::Mode) { throw Exception(Error::NotImplemented); }
void AppxBlockMapObject::CommitChanges() { throw Exception(Error::NotImplemented); }
}

Просмотреть файл

@ -4,7 +4,7 @@
#include "ZipObject.hpp"
#include "AppxPackageObject.hpp"
namespace xPlat {
namespace MSIX {
// IAppxFactory
HRESULT STDMETHODCALLTYPE AppxFactory::CreatePackageWriter (
IStream* outputStream,
@ -20,8 +20,8 @@ namespace xPlat {
{
return ResultOf([&]() {
ThrowErrorIf(Error::InvalidParameter, (packageReader == nullptr || *packageReader != nullptr), "Invalid parameter");
ComPtr<IxPlatFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IxPlatFactory>::iid, reinterpret_cast<void**>(&self)));
ComPtr<IMSIXFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IMSIXFactory>::iid, reinterpret_cast<void**>(&self)));
auto zip = ComPtr<IStorageObject>::Make<ZipObject>(self.Get(), inputStream);
auto result = ComPtr<IAppxPackageReader>::Make<AppxPackageObject>(self.Get(), m_validationOptions, zip.Get());
*packageReader = result.Detach();
@ -49,8 +49,8 @@ namespace xPlat {
*blockMapReader != nullptr
),"bad pointer.");
ComPtr<IxPlatFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IxPlatFactory>::iid, reinterpret_cast<void**>(&self)));
ComPtr<IMSIXFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IMSIXFactory>::iid, reinterpret_cast<void**>(&self)));
ComPtr<IStream> stream(inputStream);
*blockMapReader = ComPtr<IAppxBlockMapReader>::Make<AppxBlockMapObject>(self.Get(), stream).Detach();
});
@ -70,8 +70,8 @@ namespace xPlat {
*blockMapReader != nullptr
),"bad pointer.");
ComPtr<IxPlatFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IxPlatFactory>::iid, reinterpret_cast<void**>(&self)));
ComPtr<IMSIXFactory> self;
ThrowHrIfFailed(QueryInterface(UuidOfImpl<IMSIXFactory>::iid, reinterpret_cast<void**>(&self)));
auto stream = ComPtr<IStream>::Make<FileStream>(utf16_to_utf8(signatureFileName), FileStream::Mode::READ);
auto signature = ComPtr<IVerifierObject>::Make<AppxSignatureObject>(self->GetValidationOptions(), stream.Get());
auto validatedStream = signature->GetValidationStream("AppxBlockMap.xml", inputStream);
@ -107,4 +107,4 @@ namespace xPlat {
});
}
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -19,7 +19,7 @@
XERCES_CPP_NAMESPACE_USE
namespace xPlat {
namespace MSIX {
// names of footprint files.
#define APPXBLOCKMAP_XML "AppxBlockMap.xml"
@ -88,7 +88,7 @@ namespace xPlat {
{ result += found->second;
}
else
{ throw Exception(Error::AppxUnknownFileNameEncoding, fileName);
{ throw Exception(Error::UnknownFileNameEncoding, fileName);
}
i += 2;
}
@ -150,7 +150,7 @@ namespace xPlat {
m_packageId = std::make_unique<AppxPackageId>(name, version, resourceId, architecture, publisher);
}
AppxPackageObject::AppxPackageObject(IxPlatFactory* factory, APPX_VALIDATION_OPTION validation, IStorageObject* container) :
AppxPackageObject::AppxPackageObject(IMSIXFactory* factory, MSIX_VALIDATION_OPTION validation, IStorageObject* container) :
m_factory(factory),
m_validation(validation),
m_container(container)
@ -158,39 +158,39 @@ namespace xPlat {
// 1. Get the appx signature from the container and parse it
// TODO: pass validation flags and other necessary goodness through.
m_appxSignature = ComPtr<IVerifierObject>::Make<AppxSignatureObject>(validation,
((validation & APPX_VALIDATION_OPTION_SKIPSIGNATURE) == 0) ? m_container->GetFile(APPXSIGNATURE_P7X) : nullptr
((validation & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) == 0) ? m_container->GetFile(APPXSIGNATURE_P7X) : nullptr
);
if ((validation & APPX_VALIDATION_OPTION_SKIPSIGNATURE) == 0)
{ ThrowErrorIfNot(Error::AppxMissingSignatureP7X, (m_appxSignature->HasStream()), "AppxSignature.p7x not in archive!");
if ((validation & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) == 0)
{ ThrowErrorIfNot(Error::MissingAppxSignatureP7X, (m_appxSignature->HasStream()), "AppxSignature.p7x not in archive!");
}
// 2. Get content type using signature object for validation
// TODO: switch underlying type of m_contentType to something more specific.
auto temp = m_appxSignature->GetValidationStream(CONTENT_TYPES_XML, m_container->GetFile(CONTENT_TYPES_XML));
m_contentType = ComPtr<IVerifierObject>::Make<XmlObject>(temp, &contentTypesSchema);
ThrowErrorIfNot(Error::AppxMissingContentTypesXML, (m_contentType->HasStream()), "[Content_Types].xml not in archive!");
ThrowErrorIfNot(Error::MissingContentTypesXML, (m_contentType->HasStream()), "[Content_Types].xml not in archive!");
// 3. Get blockmap object using signature object for validation
temp = m_appxSignature->GetValidationStream(APPXBLOCKMAP_XML, m_container->GetFile(APPXBLOCKMAP_XML));
m_appxBlockMap = ComPtr<IVerifierObject>::Make<AppxBlockMapObject>(factory, temp);
ThrowErrorIfNot(Error::AppxMissingBlockMapXML, (m_appxBlockMap->HasStream()), "AppxBlockMap.xml not in archive!");
ThrowErrorIfNot(Error::MissingAppxBlockMapXML, (m_appxBlockMap->HasStream()), "AppxBlockMap.xml not in archive!");
// 4. Get manifest object using blockmap object for validation
// TODO: pass validation flags and other necessary goodness through.
temp = m_appxBlockMap->GetValidationStream(APPXMANIFEST_XML, m_container->GetFile(APPXMANIFEST_XML));
m_appxManifest = ComPtr<IVerifierObject>::Make<AppxManifestObject>(temp);
ThrowErrorIfNot(Error::AppxMissingAppxManifestXML, (m_appxBlockMap->HasStream()), "AppxManifest.xml not in archive!");
if ((validation & APPX_VALIDATION_OPTION_SKIPSIGNATURE) == 0)
ThrowErrorIfNot(Error::MissingAppxManifestXML, (m_appxBlockMap->HasStream()), "AppxManifest.xml not in archive!");
if ((validation & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) == 0)
{
std::string reason = "Publisher mismatch: '" + m_appxManifest->GetPublisher() + "' != '" + m_appxSignature->GetPublisher() + "'";
ThrowErrorIfNot(Error::AppxPublisherMismatch,
ThrowErrorIfNot(Error::PublisherMismatch,
(0 == m_appxManifest->GetPublisher().compare(m_appxSignature->GetPublisher())), reason);
}
struct Config
{
using lambda = std::function<xPlat::ComPtr<IStream>()>;
using lambda = std::function<MSIX::ComPtr<IStream>()>;
Config(lambda f) : GetValidationStream(f) {}
lambda GetValidationStream;
};
@ -230,19 +230,13 @@ namespace xPlat {
ThrowErrorIfNot(Error::BlockMapSemanticError, (filesToProcess.empty()), "Package not valid!");
}
void AppxPackageObject::Pack(APPX_PACKUNPACK_OPTION options, const std::string& certFile, IStorageObject* from)
{
// TODO: Implement
throw Exception(Error::NotImplemented);
}
void AppxPackageObject::Unpack(APPX_PACKUNPACK_OPTION options, IStorageObject* to)
void AppxPackageObject::Unpack(MSIX_PACKUNPACK_OPTION options, IStorageObject* to)
{
auto fileNames = GetFileNames(FileNameOptions::All);
for (const auto& fileName : fileNames)
{
std::string targetName;
if (options & APPX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER)
if (options & MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER)
{ throw Exception(Error::NotImplemented);
//targetName = GetAppxManifest()->GetPackageFullName() + to->GetPathSeparator() + fileName;
}
@ -250,7 +244,7 @@ namespace xPlat {
{ targetName = DecodeFileName(fileName);
}
auto targetFile = to->OpenFile(targetName, xPlat::FileStream::Mode::WRITE_UPDATE);
auto targetFile = to->OpenFile(targetName, MSIX::FileStream::Mode::WRITE_UPDATE);
auto sourceFile = GetFile(fileName);
ULARGE_INTEGER bytesCount = {0};
@ -288,7 +282,7 @@ namespace xPlat {
throw Exception(Error::NotImplemented);
}
IStream* AppxPackageObject::OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode)
IStream* AppxPackageObject::OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode)
{
// TODO: Implement
throw Exception(Error::NotImplemented);
@ -303,7 +297,7 @@ namespace xPlat {
// IAppxPackageReader
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetBlockMap(IAppxBlockMapReader** blockMapReader)
{
return xPlat::ResultOf([&]() {
return MSIX::ResultOf([&]() {
// TODO: Implement
throw Exception(Error::NotImplemented);
});
@ -311,7 +305,7 @@ namespace xPlat {
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetFootprintFile(APPX_FOOTPRINT_FILE_TYPE type, IAppxFile** file)
{
return xPlat::ResultOf([&]() {
return MSIX::ResultOf([&]() {
ThrowErrorIf(Error::InvalidParameter, (file == nullptr || *file != nullptr), "bad pointer");
auto footprint = footprintFiles.find(type);
ThrowErrorIf(Error::FileNotFound, (footprint == footprintFiles.end()), "unknown footprint file type");
@ -326,7 +320,7 @@ namespace xPlat {
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetPayloadFile(LPCWSTR fileName, IAppxFile** file)
{
return xPlat::ResultOf([&]() {
return MSIX::ResultOf([&]() {
ThrowErrorIf(Error::InvalidParameter, (fileName == nullptr || file == nullptr || *file != nullptr), "bad pointer");
std::string name = utf16_to_utf8(fileName);
ComPtr<IStream> stream = GetFile(name);
@ -340,7 +334,7 @@ namespace xPlat {
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetPayloadFiles(IAppxFilesEnumerator** filesEnumerator)
{
return xPlat::ResultOf([&]() {
return MSIX::ResultOf([&]() {
ThrowErrorIf(Error::InvalidParameter,(filesEnumerator == nullptr || *filesEnumerator != nullptr), "bad pointer");
ComPtr<IStorageObject> storage;
@ -352,7 +346,7 @@ namespace xPlat {
HRESULT STDMETHODCALLTYPE AppxPackageObject::GetManifest(IAppxManifestReader** manifestReader)
{
return xPlat::ResultOf([&]() {
return MSIX::ResultOf([&]() {
// TODO: Implement
throw Exception(Error::NotImplemented);
});

Просмотреть файл

@ -96,9 +96,9 @@ MIDL_DEFINE_GUID(IID, IID_IAppxEncryptedBundleWriter2,0xE644BE82,0xF0FA,0x42B8,0
//MIDL_DEFINE_GUID(IID, IID_IAppxPackageEditor,0xE2ADB6DC,0x5E71,0x4416,0x86,0xB6,0x86,0xE5,0xF5,0x29,0x1A,0x6B);
// internal interfaces.
MIDL_DEFINE_GUID(IID, IID_IAppxPackage, 0x51B2C456,0xAAA9,0x46D6,0x8E,0xC9,0x29,0x82,0x20,0x55,0x91,0x89);
MIDL_DEFINE_GUID(IID, IID_IPackage, 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);
MIDL_DEFINE_GUID(IID, IID_IMSIXFactory, 0x1f850db4,0x32b8,0x4db6,0x8b,0xf4,0x5a,0x89,0x7e,0xb6,0x11,0xf1);
MIDL_DEFINE_GUID(IID, IID_IVerifierObject, 0xcb0a105c,0x3a6c,0x4e48,0x93,0x51,0x37,0x7c,0x4d,0xcc,0xd8,0x90);
MIDL_DEFINE_GUID(IID, IID_IXmlObject, 0x0e7a446e,0xbaf7,0x44c1,0xb3,0x8a,0x21,0x6b,0xfa,0x18,0xa1,0xa8);
#undef MIDL_DEFINE_GUID

Просмотреть файл

@ -1,4 +1,4 @@
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "Exceptions.hpp"
#include "StreamBase.hpp"
#include "StorageObject.hpp"
@ -15,22 +15,22 @@
#include <functional>
#include <set>
namespace xPlat {
namespace MSIX {
AppxSignatureObject::AppxSignatureObject(APPX_VALIDATION_OPTION validationOptions, IStream* stream) :
AppxSignatureObject::AppxSignatureObject(MSIX_VALIDATION_OPTION validationOptions, IStream* stream) :
m_stream(stream),
m_validationOptions(validationOptions)
{
m_hasDigests = SignatureValidator::Validate(validationOptions, stream, m_digests, m_signatureOrigin, m_publisher);
if (0 == (validationOptions & APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_SKIPSIGNATURE))
if (0 == (validationOptions & MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_SKIPSIGNATURE))
{ // reset the source stream back to the beginning after validating it.
LARGE_INTEGER li{0};
ThrowHrIfFailed(stream->Seek(li, StreamBase::Reference::START, nullptr));
}
}
xPlat::ComPtr<IStream> AppxSignatureObject::GetValidationStream(const std::string& part, IStream* stream)
MSIX::ComPtr<IStream> AppxSignatureObject::GetValidationStream(const std::string& part, IStream* stream)
{
if (m_hasDigests)
{
@ -51,4 +51,4 @@ xPlat::ComPtr<IStream> AppxSignatureObject::GetValidationStream(const std::stri
return stream;
}
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -1,17 +1,17 @@
# xplat\src\xPlatAppx
# MSIX\src\msix
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 10/19/2017
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake) # main (top) cmake dir
set(LIBRARY_NAME xPlatAppx)
set(LIBRARY_NAME msix)
project(${LIBRARY_NAME})
# Define PALs
IF(WIN32)
set (XPLATAPPX_API=1)
set (MSIX_API=1)
set (DirectoryObject PAL/FileSystem/Win32/DirectoryObject.cpp)
set (SHA256 PAL/SHA256/Win32/SHA256.cpp)
set (Signature PAL/Signature/Win32/SignatureValidator.cpp)
@ -22,11 +22,11 @@ ELSE()
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(DEFINE_EXPORTS "-exported_symbols_list ${CMAKE_PROJECT_ROOT}/src/xPlatAppx/exports.def")
set(DEFINE_EXPORTS "-exported_symbols_list ${CMAKE_PROJECT_ROOT}/src/msix/exports.def")
ELSE()
# on Linux and linux-derived platforms, you use a version script to achieve similar ends.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(DEFINE_EXPORTS "-Wl,--version-script=${CMAKE_PROJECT_ROOT}/src/xPlatAppx/symbol.map")
set(DEFINE_EXPORTS "-Wl,--version-script=${CMAKE_PROJECT_ROOT}/src/msix/symbol.map")
ENDIF()
MESSAGE(STATUS "Using export flag: ${DEFINE_EXPORTS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${DEFINE_EXPORTS}")
@ -80,7 +80,7 @@ file(WRITE "../inc/ContentTypesSchemas.hpp" "${CONTENT_TYPES_HEADER}")
set(LIB_PUBLIC_HEADERS
../inc/AppxPackaging.hpp
../inc/AppxWindows.hpp
../inc/MSIXWindows.hpp
)
set(LIB_PRIVATE_HEADERS
@ -115,7 +115,7 @@ set(LIB_SOURCES
InflateStream.cpp
Log.cpp
UnicodeConversion.cpp
xPlatAppx.cpp
msix.cpp
ZipObject.cpp
${DirectoryObject}
${SHA256}
@ -123,7 +123,7 @@ set(LIB_SOURCES
)
# Copy out public headers
configure_file(../inc/AppxWindows.hpp ${CMAKE_CURRENT_BINARY_DIR}/AppxWindows.hpp )
configure_file(../inc/MSIXWindows.hpp ${CMAKE_CURRENT_BINARY_DIR}/MSIXWindows.hpp )
configure_file(../inc/AppxPackaging.hpp ${CMAKE_CURRENT_BINARY_DIR}/AppxPackaging.hpp)
# Define the library
@ -140,7 +140,7 @@ set_target_properties(${LIBRARY_NAME} PROPERTIES
PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
)
MESSAGE(STATUS "xPlatAppx takes a static dependency on zlib and xerces")
MESSAGE(STATUS "MSIX takes a static dependency on zlib and xerces")
include_directories(
${include_directories}
${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/zlib

Просмотреть файл

@ -8,7 +8,7 @@
#include <algorithm>
#include <cstring>
namespace xPlat {
namespace MSIX {
InflateStream::InflateStream(
IStream* stream, std::uint64_t uncompressedSize
) : m_stream(stream),
@ -190,5 +190,5 @@ namespace xPlat {
m_state = State::UNINITIALIZED;
}
}
} /* xPlat */
} /* msix */

Просмотреть файл

@ -1,7 +1,7 @@
#include "Log.hpp"
#include <string>
namespace xPlat { namespace Global { namespace Log {
namespace MSIX { namespace Global { namespace Log {
static std::string g_content;
@ -27,4 +27,4 @@ void Clear()
g_content.clear();
}
} /* log */ } /* Global */ } /* xPlat */
} /* log */ } /* Global */ } /* msix */

Просмотреть файл

@ -8,7 +8,7 @@
#include <errno.h>
#include <fts.h>
namespace xPlat {
namespace MSIX {
std::vector<std::string> DirectoryObject::GetFileNames(FileNameOptions)
{
@ -47,7 +47,7 @@ namespace xPlat {
}
}
IStream* DirectoryObject::OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode)
IStream* DirectoryObject::OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode)
{
std::string name = m_root + "/" + fileName;
auto lastSlash = name.find_last_of("/");

Просмотреть файл

@ -10,10 +10,10 @@
#include <sstream>
#include <locale>
#include <codecvt>
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
#include "UnicodeConversion.hpp"
namespace xPlat {
namespace MSIX {
enum class WalkOptions : std::uint16_t
{
Files = 1, // Enumerate files within the specified directory

Просмотреть файл

@ -3,7 +3,7 @@
#include "openssl/sha.h"
namespace xPlat {
namespace MSIX {
bool SHA256::ComputeHash(
/*in*/ std::uint8_t *buffer,
/*in*/ std::uint32_t cbBuffer,
@ -13,4 +13,4 @@ namespace xPlat {
::SHA256(buffer, cbBuffer, hash.data());
return true;
}
} // namespace xPlat {
} // namespace MSIX {

Просмотреть файл

@ -25,7 +25,7 @@ struct unique_alg_handle_deleter {
typedef std::unique_ptr<void, unique_alg_handle_deleter> unique_alg_handle;
typedef std::unique_ptr<void, unique_hash_handle_deleter> unique_hash_handle;
namespace xPlat {
namespace MSIX {
bool SHA256::ComputeHash(std::uint8_t* buffer, std::uint32_t cbBuffer, std::vector<uint8_t>& hash)
{
@ -44,7 +44,7 @@ namespace xPlat {
0); // Flags; Loads a provider which supports reusable hash
if (!NT_SUCCESS(status))
{ throw xPlat::NtStatusException(status, "failed computing SHA256 hash");
{ throw MSIX::NtStatusException(status, "failed computing SHA256 hash");
}
unique_alg_handle algHandle(algHandleT);
@ -59,7 +59,7 @@ namespace xPlat {
0); // Flags
if (!NT_SUCCESS(status) || resultLength != sizeof(hashLength))
{ throw xPlat::NtStatusException(status, "failed computing SHA256 hash");
{ throw MSIX::NtStatusException(status, "failed computing SHA256 hash");
}
// Size the hash buffer appropriately
@ -76,7 +76,7 @@ namespace xPlat {
0); // Flags
if (!NT_SUCCESS(status))
{ throw xPlat::NtStatusException(status, "failed computing SHA256 hash");
{ throw MSIX::NtStatusException(status, "failed computing SHA256 hash");
}
unique_hash_handle hashHandle(hashHandleT);
@ -89,7 +89,7 @@ namespace xPlat {
0); // Flags
if (!NT_SUCCESS(status))
{ throw xPlat::NtStatusException(status, "failed computing SHA256 hash");
{ throw MSIX::NtStatusException(status, "failed computing SHA256 hash");
}
// Obtain the hash of the message(s) into the hash buffer
@ -100,7 +100,7 @@ namespace xPlat {
0); // Flags
if (!NT_SUCCESS(status))
{ throw xPlat::NtStatusException(status, "failed computing SHA256 hash");
{ throw MSIX::NtStatusException(status, "failed computing SHA256 hash");
}
return true;

Просмотреть файл

@ -17,7 +17,7 @@
#include <openssl/pem.h>
#include <openssl/crypto.h>
namespace xPlat
namespace MSIX
{
const char* SPC_INDIRECT_DATA_OBJID = {"1.3.6.1.4.1.311.2.1.4"};
@ -126,10 +126,10 @@ namespace xPlat
}
bool ReadDigestHashes(/*[in]*/ PKCS7* p7,
/*[inout]*/ std::map<xPlat::AppxSignatureObject::DigestName, xPlat::AppxSignatureObject::Digest>& digests,
/*[inout]*/ std::map<MSIX::AppxSignatureObject::DigestName, MSIX::AppxSignatureObject::Digest>& digests,
/*[inout]*/ unique_BIO& signatureDigest)
{
ThrowErrorIf(Error::AppxSignatureInvalid,
ThrowErrorIf(Error::SignatureInvalid,
!(p7 &&
PKCS7_type_is_signed(p7) &&
p7->d.sign &&
@ -163,7 +163,7 @@ namespace xPlat
spcIndirectDataContentSize = (asn1Sequence->rle16.lengthHigh << 8) + (asn1Sequence->rle16.lengthLow);
}
ThrowErrorIf(Error::AppxSignatureInvalid,
ThrowErrorIf(Error::SignatureInvalid,
(spcIndirectDataContent == nullptr || spcIndirectDataContentSize == 0),
"bad signature data");
@ -177,7 +177,7 @@ namespace xPlat
bool found = false;
while (spcIndirectDataContent < spcIndirectDataContentEnd && !found)
{
if (*(xPlat::AppxSignatureObject::DigestName *)spcIndirectDataContent == xPlat::AppxSignatureObject::DigestName::HEAD)
if (*(MSIX::AppxSignatureObject::DigestName *)spcIndirectDataContent == MSIX::AppxSignatureObject::DigestName::HEAD)
{
found = true;
break;
@ -186,16 +186,16 @@ namespace xPlat
spcIndirectDataContentSize--;
}
ThrowErrorIf(Error::AppxSignatureInvalid, (!found), "Could not find the digest hashes in the signature");
ThrowErrorIf(Error::SignatureInvalid, (!found), "Could not find the digest hashes in the signature");
// If we found the APPX header, validate the contents
DigestHeader *header = reinterpret_cast<DigestHeader*>(spcIndirectDataContent);
std::uint32_t numberOfHashes =
(spcIndirectDataContentSize - sizeof(xPlat::AppxSignatureObject::DigestName)) / sizeof(DigestHash);
(spcIndirectDataContentSize - sizeof(MSIX::AppxSignatureObject::DigestName)) / sizeof(DigestHash);
std::uint32_t modHashes =
(spcIndirectDataContentSize - sizeof(xPlat::AppxSignatureObject::DigestName)) % sizeof(DigestHash);
ThrowErrorIf(Error::AppxSignatureInvalid, (
(header->name != xPlat::AppxSignatureObject::DigestName::HEAD) &&
(spcIndirectDataContentSize - sizeof(MSIX::AppxSignatureObject::DigestName)) % sizeof(DigestHash);
ThrowErrorIf(Error::SignatureInvalid, (
(header->name != MSIX::AppxSignatureObject::DigestName::HEAD) &&
(numberOfHashes != 4 && numberOfHashes != 5) &&
(modHashes != 0)
), "bad signature data");
@ -205,21 +205,21 @@ namespace xPlat
std::vector<std::uint8_t> hash(HASH_BYTES);
switch (header->hash[i].name)
{
case xPlat::AppxSignatureObject::DigestName::AXPC:
case xPlat::AppxSignatureObject::DigestName::AXCT:
case xPlat::AppxSignatureObject::DigestName::AXBM:
case xPlat::AppxSignatureObject::DigestName::AXCI:
case xPlat::AppxSignatureObject::DigestName::AXCD:
case MSIX::AppxSignatureObject::DigestName::AXPC:
case MSIX::AppxSignatureObject::DigestName::AXCT:
case MSIX::AppxSignatureObject::DigestName::AXBM:
case MSIX::AppxSignatureObject::DigestName::AXCI:
case MSIX::AppxSignatureObject::DigestName::AXCD:
hash.assign(&header->hash[i].content[0], &header->hash[i].content[HASH_BYTES]);
digests.emplace(header->hash[i].name, hash);
break;
default:
throw xPlat::Exception(xPlat::Error::AppxSignatureInvalid);
throw MSIX::Exception(MSIX::Error::SignatureInvalid);
}
}
ThrowErrorIf(Error::AppxSignatureInvalid,
ThrowErrorIf(Error::SignatureInvalid,
(digests.size() != 4 && digests.size() != 5),
"Digest hashes missing entries");
@ -324,30 +324,30 @@ namespace xPlat
}
bool SignatureValidator::Validate(
/*in*/ APPX_VALIDATION_OPTION option,
/*in*/ IStream *stream,
/*inout*/ std::map<xPlat::AppxSignatureObject::DigestName, xPlat::AppxSignatureObject::Digest>& digests,
/*inout*/ SignatureOrigin& origin,
/*inout*/ std::string& publisher)
MSIX_VALIDATION_OPTION option,
IStream *stream,
std::map<MSIX::AppxSignatureObject::DigestName, MSIX::AppxSignatureObject::Digest>& digests,
SignatureOrigin& origin,
std::string& publisher)
{
// If the caller wants to skip signature validation altogether, just bug out early. We will not read the digests
if (option & APPX_VALIDATION_OPTION_SKIPSIGNATURE) { return false; }
if (option & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) { return false; }
LARGE_INTEGER start = {0};
ULARGE_INTEGER end = {0};
ThrowHrIfFailed(stream->Seek(start, StreamBase::Reference::END, &end));
ThrowErrorIf(Error::AppxSignatureInvalid, (end.QuadPart <= sizeof(P7X_FILE_ID) || end.QuadPart > (2 << 20)), "stream is too big");
ThrowErrorIf(Error::SignatureInvalid, (end.QuadPart <= sizeof(P7X_FILE_ID) || end.QuadPart > (2 << 20)), "stream is too big");
ThrowHrIfFailed(stream->Seek(start, StreamBase::Reference::START, nullptr));
std::uint32_t fileID = 0;
ThrowHrIfFailed(stream->Read(&fileID, sizeof(fileID), nullptr));
ThrowErrorIf(Error::AppxSignatureInvalid, (fileID != P7X_FILE_ID), "unexpected p7x header");
ThrowErrorIf(Error::SignatureInvalid, (fileID != P7X_FILE_ID), "unexpected p7x header");
std::uint32_t p7sSize = end.u.LowPart - sizeof(fileID);
std::vector<std::uint8_t> p7s(p7sSize);
ULONG actualRead = 0;
ThrowHrIfFailed(stream->Read(p7s.data(), p7s.size(), &actualRead));
ThrowErrorIf(Error::AppxSignatureInvalid, (actualRead != p7s.size()), "read error");
ThrowErrorIf(Error::SignatureInvalid, (actualRead != p7s.size()), "read error");
// Load the p7s into a BIO buffer
unique_BIO bmem(BIO_new_mem_buf(p7s.data(), p7s.size()));
@ -375,7 +375,7 @@ namespace xPlat
unique_X509 cert(PEM_read_bio_X509(bcert.get(), nullptr, nullptr, nullptr));
// Add the cert to the trusted store
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
X509_STORE_add_cert(store.get(), cert.get()) == 1,
"Could not add cert to keychain");
@ -386,7 +386,7 @@ namespace xPlat
ReadDigestHashes(p7.get(), digests, signatureDigest);
// Loop through the untrusted certs and verify them if we're going to treat
if (APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN != (option & APPX_VALIDATION_OPTION::APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN))
if (MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN != (option & MSIX_VALIDATION_OPTION::MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN))
{
STACK_OF(X509) *untrustedCerts = p7.get()->d.sign->cert;
for (int i = 0; i < sk_X509_num(untrustedCerts); i++)
@ -403,35 +403,35 @@ namespace xPlat
X509_VERIFY_PARAM_set_flags(param,
X509_V_FLAG_CB_ISSUER_CHECK | X509_V_FLAG_TRUSTED_FIRST | X509_V_FLAG_IGNORE_CRITICAL);
ThrowErrorIfNot(Error::AppxCertNotTrusted,
ThrowErrorIfNot(Error::CertNotTrusted,
X509_verify_cert(context.get()) == 1,
"Could not verify cert");
}
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
PKCS7_verify(p7.get(), trustedChain.get(), store.get(), signatureDigest.get(), nullptr/*out*/, PKCS7_NOCRL/*flags*/) == 1,
"Could not verify package signature");
}
origin = xPlat::SignatureOrigin::Unknown;
if (IsStoreOrigin(p7s.data(), p7s.size())) { origin = xPlat::SignatureOrigin::Store; }
else if (IsAuthenticodeOrigin(p7s.data(), p7s.size())) { origin = xPlat::SignatureOrigin::LOB; }
origin = MSIX::SignatureOrigin::Unknown;
if (IsStoreOrigin(p7s.data(), p7s.size())) { origin = MSIX::SignatureOrigin::Store; }
else if (IsAuthenticodeOrigin(p7s.data(), p7s.size())) { origin = MSIX::SignatureOrigin::LOB; }
bool SignatureOriginUnknownAllowed = (option & APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN) == APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN;
ThrowErrorIf(Error::AppxCertNotTrusted,
((xPlat::SignatureOrigin::Unknown == origin) && !SignatureOriginUnknownAllowed),
bool SignatureOriginUnknownAllowed = (option & MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN) == MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN;
ThrowErrorIf(Error::CertNotTrusted,
((MSIX::SignatureOrigin::Unknown == origin) && !SignatureOriginUnknownAllowed),
"Unknown signature origin");
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
xPlat::SignatureOrigin::Store == origin ||
xPlat::SignatureOrigin::LOB == origin ||
ThrowErrorIfNot(Error::SignatureInvalid, (
MSIX::SignatureOrigin::Store == origin ||
MSIX::SignatureOrigin::LOB == origin ||
SignatureOriginUnknownAllowed
), "Signature origin check failed");
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
GetPublisherName(p7, publisher) == true
), "Signature origin check failed");
return true;
}
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -9,7 +9,7 @@
#include "FileStream.hpp"
#include "SignatureValidator.hpp"
namespace xPlat
namespace MSIX
{
struct unique_local_alloc_deleter {
void operator()(HLOCAL h) const { LocalFree(h); };
@ -76,7 +76,7 @@ namespace xPlat
CRYPT_DATA_BLOB signatureBlob = { 0 };
signatureBlob.cbData = cbSignatureBuffer;
signatureBlob.pbData = signatureBuffer;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptQueryObject(
CERT_QUERY_OBJECT_BLOB,
&signatureBlob,
@ -97,18 +97,18 @@ namespace xPlat
// The properties of the signer info will be used to uniquely identify the signing certificate in the certificate store
CMSG_SIGNER_INFO* signerInfo = NULL;
DWORD signerInfoSize = 0;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgGetParam(signedMessage.get(), CMSG_SIGNER_INFO_PARAM, 0, NULL, &signerInfoSize)
), "CryptMsgGetParam failed");
// Check that the signer info size is within reasonable bounds; under the max length of a string for the issuer field
ThrowErrorIf(Error::AppxSignatureInvalid,
ThrowErrorIf(Error::SignatureInvalid,
(signerInfoSize == 0 || signerInfoSize >= STRSAFE_MAX_CCH),
"signer info size not within reasonable bounds");
std::vector<byte> signerInfoBuffer(signerInfoSize);
signerInfo = reinterpret_cast<CMSG_SIGNER_INFO*>(signerInfoBuffer.data());
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgGetParam(signedMessage.get(), CMSG_SIGNER_INFO_PARAM, 0, signerInfo, &signerInfoSize)
), "CryptMsgGetParam failed");
@ -120,7 +120,7 @@ namespace xPlat
certStore.get(),
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
&certInfo));
ThrowErrorIf(Error::AppxSignatureInvalid, (signingCertContext.get() == NULL), "failed to get signing cert context.");
ThrowErrorIf(Error::SignatureInvalid, (signingCertContext.get() == NULL), "failed to get signing cert context.");
// Get the signing certificate chain context. Do not connect online for URL
// retrievals. Note that this check does not respect the lifetime signing
@ -130,7 +130,7 @@ namespace xPlat
certChainParameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
DWORD certChainFlags = CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL;
PCCERT_CHAIN_CONTEXT certChainContext;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CertGetCertificateChain(
HCCE_LOCAL_MACHINE,
signingCertContext.get(),
@ -153,7 +153,7 @@ namespace xPlat
std::vector<byte> extensionUsage(0);
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbExtensionUsage);
extensionUsage.resize(cbExtensionUsage);
ThrowErrorIf(Error::AppxSignatureInvalid, (
ThrowErrorIf(Error::SignatureInvalid, (
!CertGetEnhancedKeyUsage(
pCertContext,
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
@ -175,7 +175,7 @@ namespace xPlat
std::vector<byte> propertyUsage(0);
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbPropertyUsage);
propertyUsage.resize(cbPropertyUsage);
ThrowErrorIf(Error::AppxSignatureInvalid, (
ThrowErrorIf(Error::SignatureInvalid, (
!CertGetEnhancedKeyUsage(
pCertContext,
CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
@ -205,7 +205,7 @@ namespace xPlat
BYTE keyId[HASH_BYTES];
DWORD keyIdLength = HASH_BYTES;
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
(CryptHashCertificate2(
BCRYPT_SHA256_ALGORITHM,
0, // dwFlags
@ -227,7 +227,7 @@ namespace xPlat
policyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
policyParameters.dwFlags = MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG;
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
CertVerifyCertificateChainPolicy(
CERT_CHAIN_POLICY_MICROSOFT_ROOT,
certChainContext,
@ -251,7 +251,7 @@ namespace xPlat
policyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
//policyParameters.dwFlags = MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG;
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
CertVerifyCertificateChainPolicy(
CERT_CHAIN_POLICY_AUTHENTICODE,
certChainContext,
@ -265,7 +265,7 @@ namespace xPlat
policyParameters.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);
policyStatus = {0};
policyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
CertVerifyCertificateChainPolicy(
CERT_CHAIN_POLICY_BASE,
certChainContext,
@ -331,7 +331,7 @@ namespace xPlat
CERT_BLOB blob;
blob.pbData = signatureBuffer;
blob.cbData = cbSignatureBuffer;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptQueryObject(
CERT_QUERY_OBJECT_BLOB,
&blob,
@ -427,28 +427,28 @@ namespace xPlat
bool SignatureValidator::Validate(
/*in*/ APPX_VALIDATION_OPTION option,
/*in*/ IStream *stream,
/*inout*/ std::map<xPlat::AppxSignatureObject::DigestName, xPlat::AppxSignatureObject::Digest>& digests,
/*inout*/ SignatureOrigin& origin,
/*inout*/ std::string& publisher)
MSIX_VALIDATION_OPTION option,
IStream *stream,
std::map<MSIX::AppxSignatureObject::DigestName, MSIX::AppxSignatureObject::Digest>& digests,
SignatureOrigin& origin,
std::string& publisher)
{
// If the caller wants to skip signature validation altogether, just bug out early. We will not read the digests
if (option & APPX_VALIDATION_OPTION_SKIPSIGNATURE) { return false; }
if (option & MSIX_VALIDATION_OPTION_SKIPSIGNATURE) { return false; }
ThrowErrorIfNot(Error::AppxMissingSignatureP7X, (stream), "AppxSignature.p7x missing");
ThrowErrorIfNot(Error::MissingAppxSignatureP7X, (stream), "AppxSignature.p7x missing");
LARGE_INTEGER li = {0};
ULARGE_INTEGER uli = {0};
ThrowHrIfFailed(stream->Seek(li, StreamBase::Reference::END, &uli));
ThrowErrorIf(Error::AppxSignatureInvalid, (uli.QuadPart <= sizeof(P7X_FILE_ID) || uli.QuadPart > (2 << 20)), "stream is too big");
ThrowErrorIf(Error::SignatureInvalid, (uli.QuadPart <= sizeof(P7X_FILE_ID) || uli.QuadPart > (2 << 20)), "stream is too big");
std::vector<std::uint8_t> p7x(uli.LowPart);
ThrowHrIfFailed(stream->Seek(li, StreamBase::Reference::START, &uli));
ULONG actualRead = 0;
ThrowHrIfFailed(stream->Read(p7x.data(), p7x.size(), &actualRead));
ThrowErrorIf(Error::AppxSignatureInvalid,
ThrowErrorIf(Error::SignatureInvalid,
((actualRead != p7x.size() || (*(DWORD*)p7x.data() != P7X_FILE_ID))),
"Failed to read p7x or p7x header mismatch");
@ -458,7 +458,7 @@ namespace xPlat
// Decode the ASN.1 structure
CRYPT_CONTENT_INFO* contentInfo = nullptr;
DWORD contentInfoSize = 0;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS_CONTENT_INFO,
@ -477,11 +477,11 @@ namespace xPlat
NULL,
nullptr,
nullptr);
ThrowErrorIf(Error::AppxSignatureInvalid, (cryptMsgT == nullptr), "CryptMsgOpenToDecode failed");
ThrowErrorIf(Error::SignatureInvalid, (cryptMsgT == nullptr), "CryptMsgOpenToDecode failed");
unique_crypt_msg_handle cryptMsg(cryptMsgT);
// Get the crypographic message
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgUpdate(
cryptMsg.get(),
contentInfo->Content.pbData,
@ -493,7 +493,7 @@ namespace xPlat
// how big of a buffer that it needs to store the inner content
DWORD innerContentTypeSize = 0;
ULONG readBytes = 0;
ThrowErrorIf(Error::AppxSignatureInvalid, (
ThrowErrorIf(Error::SignatureInvalid, (
!CryptMsgGetParam(
cryptMsg.get(),
CMSG_INNER_CONTENT_TYPE_PARAM,
@ -505,7 +505,7 @@ namespace xPlat
// Allocate a temporary buffer
std::vector<std::uint8_t> innerContentType(innerContentTypeSize);
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgGetParam(
cryptMsg.get(),
CMSG_INNER_CONTENT_TYPE_PARAM,
@ -515,13 +515,13 @@ namespace xPlat
),"CryptMsgGetParam failed");
size_t indirectDataObjIdLength = strlen(SPC_INDIRECT_DATA_OBJID);
ThrowErrorIf(Error::AppxSignatureInvalid, (
ThrowErrorIf(Error::SignatureInvalid, (
(innerContentTypeSize != indirectDataObjIdLength + 1) ||
(strncmp((char*)innerContentType.data(), SPC_INDIRECT_DATA_OBJID, indirectDataObjIdLength + 1) != 0)
), "unexpected content type");
DWORD innerContentSize = 0;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgGetParam(
cryptMsg.get(),
CMSG_CONTENT_PARAM,
@ -533,7 +533,7 @@ namespace xPlat
// Allocate a temporary buffer
std::vector<std::uint8_t> innerContent(innerContentSize);
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptMsgGetParam(
cryptMsg.get(),
CMSG_CONTENT_PARAM,
@ -545,7 +545,7 @@ namespace xPlat
// Parse the ASN.1 to the the indirect data structure
SPC_INDIRECT_DATA_CONTENT* indirectContent = NULL;
DWORD indirectContentSize = 0;
ThrowErrorIfNot(Error::AppxSignatureInvalid, (
ThrowErrorIfNot(Error::SignatureInvalid, (
CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
SPC_INDIRECT_DATA_CONTENT_STRUCT,
@ -560,8 +560,8 @@ namespace xPlat
DigestHeader *header = reinterpret_cast<DigestHeader*>(indirectContent->Digest.pbData);
std::uint32_t numberOfHashes = (indirectContent->Digest.cbData - sizeof(DWORD)) / sizeof(DigestHash);
std::uint32_t modHashes = (indirectContent->Digest.cbData - sizeof(DWORD)) % sizeof(DigestHash);
ThrowErrorIf(Error::AppxSignatureInvalid, (
(header->name != xPlat::AppxSignatureObject::DigestName::HEAD) &&
ThrowErrorIf(Error::SignatureInvalid, (
(header->name != MSIX::AppxSignatureObject::DigestName::HEAD) &&
(numberOfHashes != 4 && numberOfHashes != 5) &&
(modHashes != 0)
), "bad signature data");
@ -571,33 +571,33 @@ namespace xPlat
std::vector<std::uint8_t> hash(HASH_BYTES);
switch (header->hash[i].name)
{
case xPlat::AppxSignatureObject::DigestName::AXPC:
case xPlat::AppxSignatureObject::DigestName::AXCT:
case xPlat::AppxSignatureObject::DigestName::AXBM:
case xPlat::AppxSignatureObject::DigestName::AXCI:
case xPlat::AppxSignatureObject::DigestName::AXCD:
case MSIX::AppxSignatureObject::DigestName::AXPC:
case MSIX::AppxSignatureObject::DigestName::AXCT:
case MSIX::AppxSignatureObject::DigestName::AXBM:
case MSIX::AppxSignatureObject::DigestName::AXCI:
case MSIX::AppxSignatureObject::DigestName::AXCD:
hash.assign(&header->hash[i].content[0], &header->hash[i].content[HASH_BYTES]);
digests.emplace(header->hash[i].name, hash);
break;
default:
throw xPlat::Exception(xPlat::Error::AppxSignatureInvalid);
throw MSIX::Exception(MSIX::Error::SignatureInvalid);
}
}
origin = xPlat::SignatureOrigin::Unknown;
if (IsStoreOrigin(p7s, p7sSize)) { origin = xPlat::SignatureOrigin::Store; }
else if (IsAuthenticodeOrigin(p7s, p7sSize)) { origin = xPlat::SignatureOrigin::LOB; }
origin = MSIX::SignatureOrigin::Unknown;
if (IsStoreOrigin(p7s, p7sSize)) { origin = MSIX::SignatureOrigin::Store; }
else if (IsAuthenticodeOrigin(p7s, p7sSize)) { origin = MSIX::SignatureOrigin::LOB; }
bool SignatureOriginUnknownAllowed = (option & APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN) == APPX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN;
ThrowErrorIf(Error::AppxCertNotTrusted,
((xPlat::SignatureOrigin::Unknown == origin) && !SignatureOriginUnknownAllowed),
bool SignatureOriginUnknownAllowed = (option & MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN) == MSIX_VALIDATION_OPTION_ALLOWSIGNATUREORIGINUNKNOWN;
ThrowErrorIf(Error::CertNotTrusted,
((MSIX::SignatureOrigin::Unknown == origin) && !SignatureOriginUnknownAllowed),
"Unknown signature origin");
ThrowErrorIfNot(Error::AppxSignatureInvalid,
ThrowErrorIfNot(Error::SignatureInvalid,
GetPublisherName(p7s, p7sSize, publisher) == true,
"Could not retrieve publisher name");
return true;
}
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -5,7 +5,7 @@
#include <codecvt>
#include "UnicodeConversion.hpp"
namespace xPlat {
namespace MSIX {
std::wstring utf8_to_utf16(const std::string& utf8string)
{
/*
@ -34,4 +34,4 @@ namespace xPlat {
std::string result(converted.begin(), converted.end());
return result;
}
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -12,7 +12,7 @@
#include <functional>
#include <algorithm>
namespace xPlat {
namespace MSIX {
/* Zip File Structure
[LocalFileHeader 1]
@ -892,7 +892,7 @@ namespace xPlat {
throw Exception(Error::NotImplemented);
}
IStream* ZipObject::OpenFile(const std::string& fileName, xPlat::FileStream::Mode mode)
IStream* ZipObject::OpenFile(const std::string& fileName, MSIX::FileStream::Mode mode)
{
throw Exception(Error::NotImplemented);
}
@ -904,7 +904,7 @@ namespace xPlat {
std::string ZipObject::GetPathSeparator() { return "/"; }
ZipObject::ZipObject(IxPlatFactory* appxFactory, IStream* stream) : m_factory(appxFactory), m_stream(stream)
ZipObject::ZipObject(IMSIXFactory* appxFactory, IStream* stream) : m_factory(appxFactory), m_stream(stream)
{
// Confirm that the file IS the correct format
EndCentralDirectoryRecord endCentralDirectoryRecord;
@ -962,7 +962,7 @@ namespace xPlat {
for (const auto& centralFileHeader : centralDirectory)
{
pos.QuadPart = centralFileHeader.second->GetRelativeOffsetOfLocalHeader();
ThrowHrIfFailed(m_stream->Seek(pos, xPlat::StreamBase::Reference::START, nullptr));
ThrowHrIfFailed(m_stream->Seek(pos, MSIX::StreamBase::Reference::START, nullptr));
auto localFileHeader = std::make_shared<LocalFileHeader>(centralFileHeader.second);
localFileHeader->Read(m_stream.Get());
fileRepository.insert(std::make_pair(
@ -987,4 +987,4 @@ namespace xPlat {
m_streams.insert(std::make_pair(centralFileHeader.second->GetFileName(), std::move(fileStream)));
}
} // ZipObject::ZipObject
} // namespace xPlat
} // namespace MSIX

Просмотреть файл

@ -1,6 +1,6 @@
# exports.def
# written 1/16/2018 by Phil Smith (psmith@microsoft.com)
# This file defines the list of c-style exports for xPlatAppx shared library
# This file defines the list of c-style exports for msix shared library
# do not remove, reorder, or overload, these exported functions as doing so
# will break the ABI contract with clients.
# ---------------------------------------------------------------------------
@ -9,4 +9,5 @@ _CoCreateAppxFactoryWithHeap
_CreateStreamOnFile
_CreateStreamOnFileUTF16
_GetLogTextUTF8
_UnpackAppx
_UnpackPackage

Просмотреть файл

@ -113,8 +113,8 @@ struct _BLOBHEADER
#include <poppack.h>
#else
// on non-win32 platforms, compile with -fvisibility=hidden
#undef XPLATAPPX_API
#define XPLATAPPX_API __attribute__((visibility("default")))
#undef MSIX_API
#define MSIX_API __attribute__((visibility("default")))
// Initializer.
__attribute__((constructor))
@ -134,90 +134,90 @@ 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,
MSIX_API HRESULT STDMETHODCALLTYPE UnpackPackage(
MSIX_PACKUNPACK_OPTION packUnpackOptions,
MSIX_VALIDATION_OPTION validationOption,
char* utf8SourcePackage,
char* utf8Destination)
{
return xPlat::ResultOf([&]() {
ThrowErrorIfNot(xPlat::Error::InvalidParameter,
return MSIX::ResultOf([&]() {
ThrowErrorIfNot(MSIX::Error::InvalidParameter,
(utf8SourcePackage != nullptr && utf8Destination != nullptr),
"Invalid parameters"
);
xPlat::ComPtr<IAppxFactory> factory;
MSIX::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(InternalAllocate, InternalFree, validationOption, &factory));
xPlat::ComPtr<IStream> stream;
MSIX::ComPtr<IStream> stream;
ThrowHrIfFailed(CreateStreamOnFile(utf8SourcePackage, true, &stream));
xPlat::ComPtr<IAppxPackageReader> reader;
MSIX::ComPtr<IAppxPackageReader> reader;
ThrowHrIfFailed(factory->CreatePackageReader(stream.Get(), &reader));
auto to = xPlat::ComPtr<IStorageObject>::Make<xPlat::DirectoryObject>(utf8Destination);
reader.As<IAppxPackage>()->Unpack(packUnpackOptions, to.Get());
auto to = MSIX::ComPtr<IStorageObject>::Make<MSIX::DirectoryObject>(utf8Destination);
reader.As<IPackage>()->Unpack(packUnpackOptions, to.Get());
});
}
XPLATAPPX_API HRESULT STDMETHODCALLTYPE GetLogTextUTF8(COTASKMEMALLOC* memalloc, char** logText)
MSIX_API HRESULT STDMETHODCALLTYPE GetLogTextUTF8(COTASKMEMALLOC* memalloc, char** logText)
{
return xPlat::ResultOf([&](){
ThrowErrorIf(xPlat::Error::InvalidParameter, (logText == nullptr || *logText != nullptr), "bad pointer" );
std::size_t countBytes = sizeof(char)*(xPlat::Global::Log::Text().size()+1);
return MSIX::ResultOf([&](){
ThrowErrorIf(MSIX::Error::InvalidParameter, (logText == nullptr || *logText != nullptr), "bad pointer" );
std::size_t countBytes = sizeof(char)*(MSIX::Global::Log::Text().size()+1);
*logText = reinterpret_cast<char*>(memalloc(countBytes));
ThrowErrorIfNot(xPlat::Error::OutOfMemory, (*logText), "Allocation failed!");
ThrowErrorIfNot(MSIX::Error::OutOfMemory, (*logText), "Allocation failed!");
std::memset(reinterpret_cast<void*>(*logText), 0, countBytes);
std::memcpy(reinterpret_cast<void*>(*logText),
reinterpret_cast<void*>(const_cast<char*>(xPlat::Global::Log::Text().c_str())),
reinterpret_cast<void*>(const_cast<char*>(MSIX::Global::Log::Text().c_str())),
countBytes - sizeof(char));
xPlat::Global::Log::Clear();
MSIX::Global::Log::Clear();
});
}
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFile(
MSIX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFile(
char* utf8File,
bool forRead,
IStream** stream)
{
return xPlat::ResultOf([&]() {
xPlat::FileStream::Mode mode = forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE;
*stream = xPlat::ComPtr<IStream>::Make<xPlat::FileStream>(utf8File, mode).Detach();
return MSIX::ResultOf([&]() {
MSIX::FileStream::Mode mode = forRead ? MSIX::FileStream::Mode::READ : MSIX::FileStream::Mode::WRITE_UPDATE;
*stream = MSIX::ComPtr<IStream>::Make<MSIX::FileStream>(utf8File, mode).Detach();
});
}
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFileUTF16(
MSIX_API HRESULT STDMETHODCALLTYPE CreateStreamOnFileUTF16(
LPCWSTR utf16File,
bool forRead,
IStream** stream)
{
return xPlat::ResultOf([&]() {
xPlat::FileStream::Mode mode = forRead ? xPlat::FileStream::Mode::READ : xPlat::FileStream::Mode::WRITE_UPDATE;
*stream = xPlat::ComPtr<IStream>::Make<xPlat::FileStream>(xPlat::utf16_to_utf8(utf16File), mode).Detach();
return MSIX::ResultOf([&]() {
MSIX::FileStream::Mode mode = forRead ? MSIX::FileStream::Mode::READ : MSIX::FileStream::Mode::WRITE_UPDATE;
*stream = MSIX::ComPtr<IStream>::Make<MSIX::FileStream>(MSIX::utf16_to_utf8(utf16File), mode).Detach();
});
}
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactoryWithHeap(
MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactoryWithHeap(
COTASKMEMALLOC* memalloc,
COTASKMEMFREE* memfree,
APPX_VALIDATION_OPTION validationOption,
MSIX_VALIDATION_OPTION validationOption,
IAppxFactory** appxFactory)
{
return xPlat::ResultOf([&]() {
*appxFactory = xPlat::ComPtr<IAppxFactory>::Make<xPlat::AppxFactory>(validationOption, memalloc, memfree).Detach();
return MSIX::ResultOf([&]() {
*appxFactory = MSIX::ComPtr<IAppxFactory>::Make<MSIX::AppxFactory>(validationOption, memalloc, memfree).Detach();
});
}
// Call specific for Windows. Default to call CoTaskMemAlloc and CoTaskMemFree
XPLATAPPX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
APPX_VALIDATION_OPTION validationOption,
MSIX_API HRESULT STDMETHODCALLTYPE CoCreateAppxFactory(
MSIX_VALIDATION_OPTION validationOption,
IAppxFactory** appxFactory)
{
#ifdef WIN32
return CoCreateAppxFactoryWithHeap(CoTaskMemAlloc, CoTaskMemFree, validationOption, appxFactory);
#else
return static_cast<HRESULT>(xPlat::Error::NotSupported);
return static_cast<HRESULT>(MSIX::Error::NotSupported);
#endif
}

Просмотреть файл

@ -5,7 +5,7 @@
CreateStreamOnFile;
CreateStreamOnFileUTF16;
GetLogTextUTF8;
UnpackAppx;
UnpackPackage;
local:
*;
};

53
src/xPlatAppx/.vscode/launch.json поставляемый
Просмотреть файл

@ -1,53 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch MakeXPlat",
"type": "cppdbg",
"request": "launch",
"program": "/Users/admin/code/xPlatAppx/build/bin/MakeXPlat",
"args": ["unpack",
"-d" ,"/Users/admin/code/xPlatAppx/test/unpack",
"-p", "/Users/admin/code/xPlatAppx/test/appx/StoreSigned_Desktop_x64_MoviesTV.appx",
"-sv"
],
"stopAtEntry": false,
"cwd": "/Users/admin/code/xPlatAppx/build/bin",
"environment": [],
"externalConsole": true,
"MIMode": "lldb"
},
{
"name": "(lldb) Launch ExtractContentsSample",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/build/bin/ExtractContentsSample",
"args": [
"${workspaceRoot}/test/appx/StoreSigned_Desktop_x64_MoviesTV.appx",
"${workspaceRoot}/test/unpack" ],
"stopAtEntry": false,
"cwd": "${workspaceRoot}/build/bin",
"environment": [],
"externalConsole": true,
"MIMode": "lldb"
},
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}\\.vs\\bin\\MakeXPlat",
"symbolSearchPath" : "${workspaceRoot}\\.vs\\bin",
"logging": {
"moduleLoad": false,
"trace": true
},
"args": ["unpack",
"-d" ,"${workspaceRoot}\\test\\unpack",
"-p", "${workspaceRoot}\\test\\appx\\UnsignedZip64WithCI-APPX_E_MISSING_REQUIRED_FILE.appx" ],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true
}
]
}

Просмотреть файл

@ -1,4 +1,4 @@
# xplat\test
# MSIX\test
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 01/29/2018
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)

Просмотреть файл

@ -3,13 +3,13 @@ TESTFAILED=0
function FindBinFolder {
echo "Searching under" $PWD
#look in .vs/bin first
if [ -e "../../.vs/bin/MakeXplat" ]
if [ -e "../../.vs/bin/makemsix" ]
then
BINDIR="../../.vs/bin"
elif [ -e "../../.vscode/bin/MakeXplat" ]
elif [ -e "../../.vscode/bin/makemsix" ]
then
BINDIR="../../.vscode/bin"
elif [ -e "../../build/bin/MakeXplat" ]
elif [ -e "../../build/bin/makemsix" ]
then
BINDIR="../../build/bin"
else
@ -33,9 +33,9 @@ function RunTest {
local UNPACKFOLDER="$2"
local ARGS="$3"
echo "------------------------------------------------------"
echo $BINDIR/MakeXplat unpack -d ./../unpack -p $UNPACKFOLDER $ARGS
echo $BINDIR/makemsix unpack -d ./../unpack -p $UNPACKFOLDER $ARGS
echo "------------------------------------------------------"
$BINDIR/MakeXplat unpack -d ./../unpack -p $UNPACKFOLDER $ARGS
$BINDIR/makemsix unpack -d ./../unpack -p $UNPACKFOLDER $ARGS
local RESULT=$?
echo "expect: "$SUCCESS", got: "$RESULT
if [ $RESULT -eq $SUCCESS ]
@ -50,7 +50,7 @@ function RunTest {
FindBinFolder
# return code is last two digits, but in decimal, not hex. e.g. 0x8bad0002 == 2, 0x8bad0041 == 65, etc...
# common codes:
# AppxSignatureInvalid = ERROR_FACILITY + 0x0041 == 65
# SignatureInvalid = ERROR_FACILITY + 0x0041 == 65
RunTest 2 ./../appx/Empty.appx -sv
RunTest 0 ./../appx/HelloWorld.appx -ss

Просмотреть файл

@ -1,6 +1,6 @@
#!/bin/bash
testfailed=0
xplatappxdir=`pwd`
projectdir=`pwd`
function RunCommandWithTimeout {
local result=1
@ -43,25 +43,25 @@ function StartEmulator {
function CreateApp {
# Prepare package and compile
cd $xplatappxdir/../mobile/xPlatAppxAndroid
cd $projectdir/../mobile/AndroidBVT
mkdir app/src/main/assets
cp -R $xplatappxdir/../appx/* app/src/main/assets
cp -R $projectdir/../appx/* app/src/main/assets
mkdir -p app/src/main/jniLibs/x86
cp $xplatappxdir/../../.vs/lib/libxPlatAppx.so app/src/main/jniLibs/x86
cp $projectdir/../../.vs/lib/libmsix.so app/src/main/jniLibs/x86
rm -r build app/build
sh ./gradlew assembleDebug
}
function RunTest {
# Install app
RunCommand "adb push app/build/outputs/apk/debug/app-debug.apk /data/local/tmp/com.microsoft.xplatappxandroid"
RunCommand "adb shell pm install -t -r '/data/local/tmp/com.microsoft.xplatappxandroid'"
RunCommand "adb push app/build/outputs/apk/debug/app-debug.apk /data/local/tmp/com.microsoft.androidbvt"
RunCommand "adb shell pm install -t -r '/data/local/tmp/com.microsoft.androidbvt'"
# Start app
RunCommand "adb shell am start -n 'com.microsoft.xplatappxandroid/com.microsoft.xplatappxandroid.MainActivity' -a android.intent.action.MAIN -c android.intent.category.LAUNCHER"
RunCommand "adb shell am start -n 'com.microsoft.androidbvt/com.microsoft.androidbvt.MainActivity' -a android.intent.action.MAIN -c android.intent.category.LAUNCHER"
# The apps terminates when is done
sleep 30
# Get Results
RunCommand "adb pull /data/data/com.microsoft.xplatappxandroid/files/testResults.txt"
RunCommand "adb pull /data/data/com.microsoft.androidbvt/files/testResults.txt"
}
function ParseResult {
@ -85,8 +85,8 @@ function ParseResult {
StartEmulator
# Clean up. This commands might fail, but is not an error
adb shell rm -r /data/data/com.microsoft.xplatappxandroid/files
rm $xplatappxdir/../mobile/xPlatAppxAndroid/testResults.txt
adb shell rm -r /data/data/com.microsoft.androidbvt/files
rm $projectdir/../mobile/androidbvt/testResults.txt
CreateApp
RunTest

Просмотреть файл

@ -4,15 +4,15 @@ $global:BINDIR=""
function FindBinFolder {
write-host "Searching under" (Get-Item -Path ".\" -Verbose).FullName
if (Test-Path "..\..\.vs\bin\MakeXplat.exe" )
if (Test-Path "..\..\.vs\bin\makemsix.exe" )
{
$global:BINDIR="..\..\.vs\bin"
}
elseif (Test-Path "..\..\.vscode\bin\MakeXplat.exe" )
elseif (Test-Path "..\..\.vscode\bin\makemsix.exe" )
{
$global:BINDIR="..\..\.vscode\bin"
}
elseif (Test-Path "..\..\build\bin\MakeXplat.exe")
elseif (Test-Path "..\..\build\bin\makemsix.exe")
{
$global:BINDIR="..\..\build\bin"
}
@ -46,10 +46,10 @@ function RunTest([int] $SUCCESSCODE, [string] $PACKAGE, [string] $OPT) {
CleanupUnpackFolder
$OPTIONS = "unpack -d .\..\unpack -p $PACKAGE $OPT"
write-host "------------------------------------------------------"
write-host "$BINDIR\MakeXplat.exe $OPTIONS"
write-host "$BINDIR\makemsix.exe $OPTIONS"
write-host "------------------------------------------------------"
$p = Start-Process $BINDIR\MakeXplat.exe -ArgumentList "$OPTIONS" -wait -NoNewWindow -PassThru
$p = Start-Process $BINDIR\makemsix.exe -ArgumentList "$OPTIONS" -wait -NoNewWindow -PassThru
#$p.HasExited
$ERRORCODE = $p.ExitCode
$a = "{0:x0}" -f $SUCCESSCODE

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.4.1)
include_directories(
${include_directories}
../../common
../../../../src/inc
)
add_library(native-lib SHARED
../../common/MobileTests.cpp
src/main/cpp/native-lib.cpp
)
# Add our msix library
add_library(msix-lib SHARED IMPORTED GLOBAL)
set_target_properties(msix-lib PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/x86/libmsix.so)
target_link_libraries(native-lib msix-lib android log)

Просмотреть файл

@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.microsoft.xplatappxandroid"
applicationId "com.microsoft.androidbvt"
minSdkVersion 19
targetSdkVersion 26
versionCode 1

Просмотреть файл

Просмотреть файл

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.xplatappxandroid">
package="com.microsoft.androidbvt">
<application
android:allowBackup="true"

Просмотреть файл

@ -8,7 +8,7 @@
#include <android/log.h>
#include "MobileTests.hpp"
#include "AppxWindows.hpp"
#include "MSIXWindows.hpp"
std::string GetStringPathFromJString(JNIEnv* env, jstring jFilePath)
{
@ -23,7 +23,7 @@ void CopyFilesFromAssets(JNIEnv* env, jobject assetManager, std::string filePath
if (!subDirectory.empty())
{ std::string path = filePath + subDirectory;
if (-1 == mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST)
{ __android_log_print(ANDROID_LOG_ERROR, "xPlatAppx", "Error creating directory: %s", strerror(errno));
{ __android_log_print(ANDROID_LOG_ERROR, "MSIX", "Error creating directory: %s", strerror(errno));
}
}
@ -32,33 +32,33 @@ void CopyFilesFromAssets(JNIEnv* env, jobject assetManager, std::string filePath
const char* fileName;
int count = 0;
while ((fileName = AAssetDir_getNextFileName(assetDir)) != nullptr)
{ std::string appxFileName;
{ std::string relativeFile;
// fileName is relative to the opened dir. AAssetManager_open needs the relative
// path from the assets directory.
if(!subDirectory.empty())
{ appxFileName = subDirectory + "/" + std::string(fileName);
if (!subDirectory.empty())
{ relativeFile = subDirectory + "/" + std::string(fileName);
}
else
{ appxFileName = std::string(fileName);
{ relativeFile = std::string(fileName);
}
// Get asset and copy it.
AAsset* appxAsset = AAssetManager_open(manager, appxFileName.c_str(), AASSET_MODE_STREAMING);
AAsset* asset = AAssetManager_open(manager, relativeFile.c_str(), AASSET_MODE_STREAMING);
int bytesRead = 0;
char buffer[BUFSIZ];
std::string fileToCreate = filePath + std::string(appxFileName);
__android_log_print(ANDROID_LOG_INFO, "xPlatAppx", "File: %s", fileToCreate.c_str());
FILE* appxFile = fopen(fileToCreate.c_str(), "w");
if(appxFile == nullptr)
{ __android_log_print(ANDROID_LOG_ERROR, "xPlatAppx", "File: %s Error: %s", fileToCreate.c_str(), strerror(errno));
std::string fileToCreate = filePath + std::string(relativeFile);
__android_log_print(ANDROID_LOG_INFO, "MSIX", "File: %s", fileToCreate.c_str());
FILE* newFile = fopen(fileToCreate.c_str(), "w");
if (newFile == nullptr)
{ __android_log_print(ANDROID_LOG_ERROR, "MSIX", "File: %s Error: %s", fileToCreate.c_str(), strerror(errno));
}
else
{ while ((bytesRead = AAsset_read(appxAsset, buffer, BUFSIZ)) > 0)
{ fwrite(buffer, bytesRead, 1, appxFile);
{ while ((bytesRead = AAsset_read(asset, buffer, BUFSIZ)) > 0)
{ fwrite(buffer, bytesRead, 1, newFile);
}
fclose(appxFile);
fclose(newFile);
}
AAsset_close(appxAsset);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
}
@ -67,7 +67,7 @@ extern "C"
JNIEXPORT jstring
JNICALL
Java_com_microsoft_xplatappxandroid_MainActivity_RunTests(JNIEnv* env, jobject /* this */,
Java_com_microsoft_androidbvt_MainActivity_RunTests(JNIEnv* env, jobject /* this */,
jobject assetManager, jstring jFilePath)
{
std::string output = "Test failure";

Просмотреть файл

@ -1,4 +1,4 @@
package com.microsoft.xplatappxandroid;
package com.microsoft.androidbvt;
import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
@ -25,7 +25,6 @@ public class MainActivity extends AppCompatActivity {
// Get assets resource manager
mgr = getResources().getAssets();
// getFilesDir creates a files directory if not present.
// This seems fine to cleaner on where we copy the appxs
tv.setText(RunTests(mgr, this.getFilesDir().toString()));
// Terminate app

Просмотреть файл

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.microsoft.xplatappxandroid.MainActivity">
tools:context="com.microsoft.androidbvt.MainActivity">
<TextView
android:id="@+id/sample_text"

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.0 KiB

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 4.9 KiB

После

Ширина:  |  Высота:  |  Размер: 4.9 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.0 KiB

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.8 KiB

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 4.5 KiB

После

Ширина:  |  Высота:  |  Размер: 4.5 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 6.9 KiB

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 6.3 KiB

После

Ширина:  |  Высота:  |  Размер: 6.3 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 10 KiB

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 9.0 KiB

После

Ширина:  |  Высота:  |  Размер: 9.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 15 KiB

После

Ширина:  |  Высота:  |  Размер: 15 KiB

Просмотреть файл

@ -0,0 +1,3 @@
<resources>
<string name="app_name">AndroidBVT</string>
</resources>

0
test/mobile/xPlatAppxAndroid/gradlew → test/mobile/AndroidBVT/gradlew поставляемый Executable file → Normal file
Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -1,4 +1,4 @@
# xplat\test\mobile
# MSIX\test\mobile
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 01/29/2018
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)

Просмотреть файл

@ -1,9 +1,9 @@
# xplat\test\mobile\common
# MSIX\test\mobile\common
# Copyright (C) 2017 Microsoft
# Created by Phil Smith (psmith@microsoft.com) on 01/29/2018
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake) # main (top) cmake dir
set(LIBRARY_NAME xPlatAppxTestCommon)
set(LIBRARY_NAME msixtestcommon)
project(${LIBRARY_NAME})
# Visibility variables for non-win32 platforms
@ -42,5 +42,5 @@ include_directories(
${CMAKE_PROJECT_ROOT}/src/inc
)
target_link_libraries(${PROJECT_NAME} PRIVATE xPlatAppx)
target_link_libraries(${PROJECT_NAME} PRIVATE msix)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше