Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 87 additions & 86 deletions src/inc/internal/AppxBundleWriter.hpp
Original file line number Diff line number Diff line change
@@ -1,86 +1,87 @@
//
// Copyright (C) 2019 Microsoft. All rights reserved.
// See LICENSE file in the project root for full license information.
//
#pragma once

#include "AppxPackaging.hpp"
#include "ComHelper.hpp"
#include "DirectoryObject.hpp"
#include "AppxBlockMapWriter.hpp"
#include "ContentTypeWriter.hpp"
#include "ZipObjectWriter.hpp"
#include "BundleWriterHelper.hpp"
#include "BundleManifestWriter.hpp"
#include "AppxPackageInfo.hpp"

// internal interface
// {ca90bcd9-78a2-4773-820c-0b687de49f99}
#ifndef WIN32
interface IBundleWriter : public IUnknown
#else
#include "Unknwn.h"
#include "Objidl.h"
class IBundleWriter : public IUnknown
#endif
{
public:
virtual void ProcessBundlePayload(const MSIX::ComPtr<IDirectoryObject>& from, bool flatBundle) = 0;
virtual void ProcessBundlePayloadFromMappingFile(std::map<std::string, std::string> fileList, bool flatBundle) = 0;
virtual void ProcessExternalPackages(std::map<std::string, std::string> externalPackagesList) = 0;
};
MSIX_INTERFACE(IBundleWriter, 0xca90bcd9,0x78a2,0x4773,0x82,0x0c,0x0b,0x68,0x7d,0xe4,0x9f,0x99);

namespace MSIX {
class AppxBundleWriter final : public ComClass<AppxBundleWriter, IBundleWriter, IAppxBundleWriter, IAppxBundleWriter4>
{
public:
AppxBundleWriter(IMsixFactory* factory, const ComPtr<IZipWriter>& zip, std::uint64_t bundleVersion);
~AppxBundleWriter() {};

// IBundleWriter
void ProcessBundlePayload(const ComPtr<IDirectoryObject>& from, bool flatBundle) override;
void ProcessBundlePayloadFromMappingFile(std::map<std::string, std::string> fileList, bool flatBundle) override;
void ProcessExternalPackages(std::map<std::string, std::string> externalPackagesList) override;

// IAppxBundleWriter
HRESULT STDMETHODCALLTYPE AddPayloadPackage(LPCWSTR fileName, IStream* packageStream) noexcept override;
HRESULT STDMETHODCALLTYPE Close() noexcept override;

// IAppxBundleWriter4
HRESULT STDMETHODCALLTYPE AddPackageReference(LPCWSTR fileName, IStream* inputStream,
BOOL isDefaultApplicablePackage) noexcept override;
HRESULT STDMETHODCALLTYPE AddPayloadPackage(LPCWSTR fileName, IStream* packageStream,
BOOL isDefaultApplicablePackage) noexcept override;
HRESULT STDMETHODCALLTYPE AddExternalPackageReference(LPCWSTR fileName, IStream* inputStream,
BOOL isDefaultApplicablePackage) noexcept override;

protected:
typedef enum
{
Open = 1,
Closed = 2,
Failed = 3
}
WriterState;

void AddFileToPackage(const std::string& name, IStream* stream, bool toCompress,
bool addToBlockMap, const char* contentType, bool forceContentTypeOverride = false);

void AddPackageReferenceInternal(std::string fileName, IStream* packageStream, bool isDefaultApplicablePackage);

void AddExternalPackageReferenceInternal(std::string fileName, IStream* packageStream, bool isDefaultApplicablePackage);

void ValidateAndAddPayloadFile(const std::string& name, IStream* stream, APPX_COMPRESSION_OPTION compressionOpt, const char* contentType);

void ValidateCompressionOption(APPX_COMPRESSION_OPTION compressionOpt);

WriterState m_state;
ComPtr<IMsixFactory> m_factory;
ComPtr<IZipWriter> m_zipWriter;
BlockMapWriter m_blockMapWriter;
ContentTypeWriter m_contentTypeWriter;
BundleWriterHelper m_bundleWriterHelper;
};
}

//
// Copyright (C) 2019 Microsoft. All rights reserved.
// See LICENSE file in the project root for full license information.
//
#pragma once

#include "AppxPackaging.hpp"
#include "ComHelper.hpp"
#include "DirectoryObject.hpp"
#include "AppxBlockMapWriter.hpp"
#include "ContentTypeWriter.hpp"
#include "ZipObjectWriter.hpp"
#include "BundleWriterHelper.hpp"
#include "BundleManifestWriter.hpp"
#include "AppxPackageInfo.hpp"

// internal interface
// {ca90bcd9-78a2-4773-820c-0b687de49f99}
#ifndef WIN32
interface IBundleWriter : public IUnknown
#else
#include "Unknwn.h"
#include "Objidl.h"
class IBundleWriter : public IUnknown
#endif
{
public:
virtual void ProcessBundlePayload(const MSIX::ComPtr<IDirectoryObject>& from, bool flatBundle) = 0;
virtual void ProcessBundlePayloadFromMappingFile(std::map<std::string, std::string> fileList, bool flatBundle) = 0;
virtual void ProcessExternalPackages(std::map<std::string, std::string> externalPackagesList) = 0;
};
MSIX_INTERFACE(IBundleWriter, 0xca90bcd9,0x78a2,0x4773,0x82,0x0c,0x0b,0x68,0x7d,0xe4,0x9f,0x99);

namespace MSIX {
class AppxBundleWriter final : public ComClass<AppxBundleWriter, IBundleWriter, IAppxBundleWriter, IAppxBundleWriter4>
{
public:
AppxBundleWriter(IMsixFactory* factory, const ComPtr<IZipWriter>& zip, std::uint64_t bundleVersion);
~AppxBundleWriter() {};

// IBundleWriter
void ProcessBundlePayload(const ComPtr<IDirectoryObject>& from, bool flatBundle) override;
void ProcessBundlePayloadFromMappingFile(std::map<std::string, std::string> fileList, bool flatBundle) override;
void ProcessExternalPackages(std::map<std::string, std::string> externalPackagesList) override;

// IAppxBundleWriter
HRESULT STDMETHODCALLTYPE AddPayloadPackage(LPCWSTR fileName, IStream* packageStream) noexcept override;
HRESULT STDMETHODCALLTYPE Close() noexcept override;

// IAppxBundleWriter4
HRESULT STDMETHODCALLTYPE AddPackageReference(LPCWSTR fileName, IStream* inputStream,
BOOL isDefaultApplicablePackage) noexcept override;
HRESULT STDMETHODCALLTYPE AddPayloadPackage(LPCWSTR fileName, IStream* packageStream,
BOOL isDefaultApplicablePackage) noexcept override;
HRESULT STDMETHODCALLTYPE AddExternalPackageReference(LPCWSTR fileName, IStream* inputStream,
BOOL isDefaultApplicablePackage) noexcept override;

protected:
typedef enum
{
Open = 1,
Closed = 2,
Failed = 3
}
WriterState;

// Returns the offset of the file in the bundle
std::uint64_t AddFileToPackage(const std::string& name, IStream* stream, bool toCompress,
bool addToBlockMap, const char* contentType, bool forceContentTypeOverride = false);

void AddPackageReferenceInternal(std::string fileName, IStream* packageStream, bool isDefaultApplicablePackage);

void AddExternalPackageReferenceInternal(std::string fileName, IStream* packageStream, bool isDefaultApplicablePackage);

void ValidateAndAddPayloadFile(const std::string& name, IStream* stream, APPX_COMPRESSION_OPTION compressionOpt, const char* contentType);

void ValidateCompressionOption(APPX_COMPRESSION_OPTION compressionOpt);

WriterState m_state;
ComPtr<IMsixFactory> m_factory;
ComPtr<IZipWriter> m_zipWriter;
BlockMapWriter m_blockMapWriter;
ContentTypeWriter m_contentTypeWriter;
BundleWriterHelper m_bundleWriterHelper;
};
}

145 changes: 73 additions & 72 deletions src/inc/internal/ZipObjectWriter.hpp
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
//
// Copyright (C) 2019 Microsoft. All rights reserved.
// See LICENSE file in the project root for full license information.
//
#pragma once

#include "AppxPackaging.hpp"
#include "Exceptions.hpp"
#include "ComHelper.hpp"
#include "ZipObject.hpp"

#include <vector>
#include <map>
#include <memory>
#include <utility>

#include <zlib.h>

// {350dd671-0c40-4cd7-9a5b-27456d604bd0}
#ifndef WIN32
interface IZipWriter : public IUnknown
#else
#include "Unknwn.h"
#include "Objidl.h"
class IZipWriter : public IUnknown
#endif
{
public:
// Writes the lfh header to the stream and return the size of the header
virtual std::pair<std::uint32_t, MSIX::ComPtr<IStream>> PrepareToAddFile(const std::string& name, bool isCompressed) = 0;

// Ends the file, rewrites the LFH or writes data descriptor and adds an entry
// to the central directories map
virtual void EndFile(std::uint32_t crc, std::uint64_t compressedSize, std::uint64_t uncompressedSize, bool forceDataDescriptor) = 0;

// Ends zip file by writing the central directory records, zip64 locator,
// zip64 end of central directory and the end of central directories.
virtual void Close() = 0;
};
MSIX_INTERFACE(IZipWriter, 0x350dd671,0x0c40,0x4cd7,0x9a,0x5b,0x27,0x45,0x6d,0x60,0x4b,0xd0);

namespace MSIX {

class ZipObjectWriter final : public ComClass<ZipObjectWriter, IStorageObject, IZipWriter>, ZipObject
{
public:
ZipObjectWriter(const ComPtr<IStream>& stream);

ZipObjectWriter(const ComPtr<IStorageObject>& storageObject);

// IStorage methods
std::vector<std::string> GetFileNames(FileNameOptions options) override;
ComPtr<IStream> GetFile(const std::string& fileName) override;
std::string GetFileName() override { NOTIMPLEMENTED };

// IZipWriter
std::pair<std::uint32_t, ComPtr<IStream>> PrepareToAddFile(const std::string& name, bool isCompressed) override;
void EndFile(std::uint32_t crc, std::uint64_t compressedSize, std::uint64_t uncompressedSize, bool forceDataDescriptor) override;
void Close() override;

protected:
enum class State
{
ReadyForLfhOrClose,
ReadyForFile,
Closed,
};

State m_state = State::ReadyForLfhOrClose;
std::pair<std::uint64_t, LocalFileHeader> m_lastLFH;
std::vector<std::string> m_fileNameSequence;
};
//
// Copyright (C) 2019 Microsoft. All rights reserved.
// See LICENSE file in the project root for full license information.
//
#pragma once

#include "AppxPackaging.hpp"
#include "Exceptions.hpp"
#include "ComHelper.hpp"
#include "ZipObject.hpp"

#include <vector>
#include <map>
#include <memory>
#include <utility>
#include <tuple>

#include <zlib.h>

// {350dd671-0c40-4cd7-9a5b-27456d604bd0}
#ifndef WIN32
interface IZipWriter : public IUnknown
#else
#include "Unknwn.h"
#include "Objidl.h"
class IZipWriter : public IUnknown
#endif
{
public:
// Writes the lfh header to the stream and return the offset of the header, size of the header and the stream
virtual std::tuple<std::uint64_t, std::uint32_t, MSIX::ComPtr<IStream>> PrepareToAddFile(const std::string& name, bool isCompressed) = 0;

// Ends the file, rewrites the LFH or writes data descriptor and adds an entry
// to the central directories map
virtual void EndFile(std::uint32_t crc, std::uint64_t compressedSize, std::uint64_t uncompressedSize, bool forceDataDescriptor) = 0;

// Ends zip file by writing the central directory records, zip64 locator,
// zip64 end of central directory and the end of central directories.
virtual void Close() = 0;
};
MSIX_INTERFACE(IZipWriter, 0x350dd671,0x0c40,0x4cd7,0x9a,0x5b,0x27,0x45,0x6d,0x60,0x4b,0xd0);

namespace MSIX {

class ZipObjectWriter final : public ComClass<ZipObjectWriter, IStorageObject, IZipWriter>, ZipObject
{
public:
ZipObjectWriter(const ComPtr<IStream>& stream);

ZipObjectWriter(const ComPtr<IStorageObject>& storageObject);

// IStorage methods
std::vector<std::string> GetFileNames(FileNameOptions options) override;
ComPtr<IStream> GetFile(const std::string& fileName) override;
std::string GetFileName() override { NOTIMPLEMENTED };

// IZipWriter
std::tuple<std::uint64_t, std::uint32_t, ComPtr<IStream>> PrepareToAddFile(const std::string& name, bool isCompressed) override;
void EndFile(std::uint32_t crc, std::uint64_t compressedSize, std::uint64_t uncompressedSize, bool forceDataDescriptor) override;
void Close() override;

protected:
enum class State
{
ReadyForLfhOrClose,
ReadyForFile,
Closed,
};

State m_state = State::ReadyForLfhOrClose;
std::pair<std::uint64_t, LocalFileHeader> m_lastLFH;
std::vector<std::string> m_fileNameSequence;
};
}
Loading