Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extensions can implement custom container compression #510

Closed
Closed
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
38 changes: 38 additions & 0 deletions src/api/burn/bextutil/inc/BextBaseBootstrapperExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,44 @@ class CBextBaseBootstrapperExtension : public IBootstrapperExtension
return E_NOTIMPL;
}

virtual STDMETHODIMP ContainerOpen(
__in LPCWSTR /*wzContainerId*/,
__in LPCWSTR /*wzFilePath*/,
__out LPVOID* /*pContext*/
)
{
return E_NOTIMPL;
}

virtual STDMETHODIMP ContainerOpenAttached(
__in LPCWSTR /*wzContainerId*/,
__in HANDLE /*hBundle*/,
__in DWORD64 /*qwContainerStartPos*/,
__in DWORD64 /*qwContainerSize*/,
__out LPVOID* /*ppContext*/
)
{
return E_NOTIMPL;
}

virtual STDMETHODIMP ContainerExtractFiles(
__in LPVOID /*pContext*/,
__in DWORD /*cFiles*/,
__in LPCWSTR */*psczEmbeddedIds*/,
__in LPCWSTR */*psczTargetPaths*/
)
{
return E_NOTIMPL;
}

// Don't forget to release everything in the context
virtual STDMETHODIMP ContainerClose(
__in LPVOID /*pContext*/
)
{
return E_NOTIMPL;
}

virtual STDMETHODIMP BootstrapperExtensionProc(
__in BOOTSTRAPPER_EXTENSION_MESSAGE /*message*/,
__in const LPVOID /*pvArgs*/,
Expand Down
48 changes: 48 additions & 0 deletions src/api/burn/bextutil/inc/BextBaseBootstrapperExtensionProc.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@ static HRESULT BextBaseBEProcSearch(
return pBE->Search(pArgs->wzId, pArgs->wzVariable);
}

static HRESULT BextBaseBEProcContainerOpen(
__in IBootstrapperExtension* pBE,
__in BUNDLE_EXTENSION_CONTAINER_OPEN_ARGS* pArgs,
__inout BUNDLE_EXTENSION_CONTAINER_OPEN_RESULTS* pResults
)
{
return pBE->ContainerOpen(pArgs->wzContainerId, pArgs->wzFilePath, &pResults->pContext);
}

static HRESULT BextBaseBEProcContainerOpenAttached(
__in IBootstrapperExtension* pBE,
__in BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_ARGS* pArgs,
__inout BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_RESULTS* pResults
)
{
return pBE->ContainerOpenAttached(pArgs->wzContainerId, pArgs->hBundle, pArgs->qwContainerStartPos, pArgs->qwContainerSize, &pResults->pContext);
}

static HRESULT BextBaseBEProcContainerExtractFiles(
__in IBootstrapperExtension* pBE,
__in BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_ARGS* pArgs,
__inout BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_RESULTS* /*pResults*/
)
{
return pBE->ContainerExtractFiles(pArgs->pContext, pArgs->cFiles, pArgs->psczEmbeddedIds, pArgs->psczTargetPaths);
}

static HRESULT BextBaseBEProcContainerClose(
__in IBootstrapperExtension* pBE,
__in BUNDLE_EXTENSION_CONTAINER_CLOSE_ARGS* pArgs,
__inout BUNDLE_EXTENSION_CONTAINER_CLOSE_RESULTS* /*pResults*/
)
{
return pBE->ContainerClose(pArgs->pContext);
}

/*******************************************************************
BextBaseBootstrapperExtensionProc - requires pvContext to be of type IBootstrapperExtension.
Provides a default mapping between the message based
Expand All @@ -39,6 +75,18 @@ static HRESULT WINAPI BextBaseBootstrapperExtensionProc(
case BOOTSTRAPPER_EXTENSION_MESSAGE_SEARCH:
hr = BextBaseBEProcSearch(pBE, reinterpret_cast<BOOTSTRAPPER_EXTENSION_SEARCH_ARGS*>(pvArgs), reinterpret_cast<BOOTSTRAPPER_EXTENSION_SEARCH_RESULTS*>(pvResults));
break;
case BUNDLE_EXTENSION_MESSAGE_CONTAINER_OPEN:
hr = BextBaseBEProcContainerOpen(pBE, reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_OPEN_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_OPEN_RESULTS*>(pvResults));
break;
case BUNDLE_EXTENSION_MESSAGE_CONTAINER_OPEN_ATTACHED:
hr = BextBaseBEProcContainerOpenAttached(pBE, reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_RESULTS*>(pvResults));
break;
case BUNDLE_EXTENSION_MESSAGE_CONTAINER_EXTRACT_FILES:
hr = BextBaseBEProcContainerExtractFiles(pBE, reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_RESULTS*>(pvResults));
break;
case BUNDLE_EXTENSION_MESSAGE_CONTAINER_CLOSE:
hr = BextBaseBEProcContainerClose(pBE, reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_CLOSE_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_CONTAINER_CLOSE_RESULTS*>(pvResults));
break;
}
}

Expand Down
38 changes: 38 additions & 0 deletions src/api/burn/bextutil/inc/IBootstrapperExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,44 @@ DECLARE_INTERFACE_IID_(IBootstrapperExtension, IUnknown, "93123C9D-796B-4FCD-A50
__in LPCWSTR wzVariable
) = 0;

/* ContainerOpen
Open a container file.
*/
STDMETHOD(ContainerOpen)(
__in LPCWSTR wzContainerId,
__in LPCWSTR wzFilePath,
__out LPVOID *ppContext
) = 0;

/* ContainerOpenAttached
Open an attached container.
If not implemented, return E_NOTIMPL. In that case, burn will extract the container to a temporary file and call ContainerOpen(). Note that, this may come with substantial performance penalty
*/
STDMETHOD(ContainerOpenAttached)(
__in LPCWSTR wzContainerId,
__in HANDLE hBundle,
__in DWORD64 qwContainerStartPos,
__in DWORD64 qwContainerSize,
__out LPVOID *ppContext
) = 0;

/* ContainerExtractFiles
Extract files.
*/
STDMETHOD(ContainerExtractFiles)(
__in LPVOID pContext,
__in DWORD cFiles,
__in LPCWSTR *psczEmbeddedIds,
__in LPCWSTR *psczTargetPaths
) = 0;

/* ContainerClose
Release the container.
*/
STDMETHOD(ContainerClose)(
__in LPVOID pContext
) = 0;

// BootstrapperExtensionProc - The PFN_BOOTSTRAPPER_EXTENSION_PROC can call this method to give the BootstrapperExtension raw access to the callback from the engine.
// This might be used to help the BootstrapperExtension support more than one version of the engine.
STDMETHOD(BootstrapperExtensionProc)(
Expand Down
58 changes: 58 additions & 0 deletions src/api/burn/inc/BootstrapperExtensionTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ extern "C" {
enum BOOTSTRAPPER_EXTENSION_MESSAGE
{
BOOTSTRAPPER_EXTENSION_MESSAGE_SEARCH,
BUNDLE_EXTENSION_MESSAGE_CONTAINER_OPEN,
BUNDLE_EXTENSION_MESSAGE_CONTAINER_OPEN_ATTACHED,
BUNDLE_EXTENSION_MESSAGE_CONTAINER_EXTRACT_FILES,
BUNDLE_EXTENSION_MESSAGE_CONTAINER_CLOSE,
};

typedef struct _BOOTSTRAPPER_EXTENSION_SEARCH_ARGS
Expand All @@ -24,6 +28,60 @@ typedef struct _BOOTSTRAPPER_EXTENSION_SEARCH_RESULTS
DWORD cbSize;
} BOOTSTRAPPER_EXTENSION_SEARCH_RESULTS;

// Container ops arguments
typedef struct _BUNDLE_EXTENSION_CONTAINER_OPEN_ARGS
{
DWORD cbSize;
LPCWSTR wzContainerId;
LPCWSTR wzFilePath;
} BUNDLE_EXTENSION_CONTAINER_OPEN_ARGS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_OPEN_RESULTS
{
DWORD cbSize;
LPVOID pContext;
} BUNDLE_EXTENSION_CONTAINER_OPEN_RESULTS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_ARGS
{
DWORD cbSize;
LPCWSTR wzContainerId;
HANDLE hBundle;
DWORD64 qwContainerStartPos;
DWORD64 qwContainerSize;
} BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_ARGS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_RESULTS
{
DWORD cbSize;
LPVOID pContext;
} BUNDLE_EXTENSION_CONTAINER_OPEN_ATTACHED_RESULTS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_ARGS
{
DWORD cbSize;
LPVOID pContext;
DWORD cFiles;
LPCWSTR *psczEmbeddedIds;
LPCWSTR *psczTargetPaths;
} BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_ARGS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_RESULTS
{
DWORD cbSize;
} BUNDLE_EXTENSION_CONTAINER_EXTRACT_FILES_RESULTS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_CLOSE_ARGS
{
DWORD cbSize;
LPVOID pContext;
} BUNDLE_EXTENSION_CONTAINER_CLOSE_ARGS;

typedef struct _BUNDLE_EXTENSION_CONTAINER_CLOSE_RESULTS
{
DWORD cbSize;
} BUNDLE_EXTENSION_CONTAINER_CLOSE_RESULTS;

extern "C" typedef HRESULT(WINAPI *PFN_BOOTSTRAPPER_EXTENSION_PROC)(
__in BOOTSTRAPPER_EXTENSION_MESSAGE message,
__in const LPVOID pvArgs,
Expand Down
18 changes: 18 additions & 0 deletions src/api/wix/WixToolset.Data/ErrorMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,21 @@ public static Message IllegalAttributeWhenNested(SourceLineNumber sourceLineNumb
return Message(sourceLineNumbers, Ids.IllegalAttributeWhenNested, "The File element contains an attribute '{0}' that cannot be used in a File element that is a child of a Component element.", attributeName);
}

public static Message MissingContainerExtension(SourceLineNumber sourceLineNumber, string containerId, string bundleExtensionRef)
{
return Message(sourceLineNumber, Ids.MissingContainerExtension, "Container '{0}' has BundleExtensionRef set to '{1}', which could not be resolved to a container extension.", containerId, bundleExtensionRef);
}

public static Message ContainerExtractFailed(SourceLineNumber sourceLineNumber, string containerId, string bundleExtensionRef, string errorMessage)
{
return Message(sourceLineNumber, Ids.ContainerExtractFailed, "Container '{0}' with BundleExtensionRef set to '{1}' failed to extract the container. {2}", containerId, bundleExtensionRef, errorMessage);
}

public static Message InvalidBurnManifestContainers(SourceLineNumber sourceLineNumber, int containersCount, int missingIndex)
{
return Message(sourceLineNumber, Ids.InvalidBurnManifestContainers, "The burn manifest file contains {0} containers, yet container with index {1} was not found.", containersCount, missingIndex);
}

private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
{
return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
Expand Down Expand Up @@ -2667,6 +2682,9 @@ public enum Ids
MsiTransactionInvalidPackage2 = 412,
ExpectedAttributeOrElementWithOtherAttribute = 413,
ExpectedAttributeOrElementWithoutOtherAttribute = 414,
MissingContainerExtension = 415,
ContainerExtractFailed = 416,
InvalidBurnManifestContainers = 417,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public static partial class SymbolDefinitions
new IntermediateFieldDefinition(nameof(WixBundleContainerSymbolFields.Hash), IntermediateFieldType.String),
new IntermediateFieldDefinition(nameof(WixBundleContainerSymbolFields.AttachedContainerIndex), IntermediateFieldType.Number),
new IntermediateFieldDefinition(nameof(WixBundleContainerSymbolFields.WorkingPath), IntermediateFieldType.String),
new IntermediateFieldDefinition(nameof(WixBundleContainerSymbolFields.BundleExtensionRef), IntermediateFieldType.String),
},
typeof(WixBundleContainerSymbol));
}
Expand All @@ -35,6 +36,7 @@ public enum WixBundleContainerSymbolFields
Hash,
AttachedContainerIndex,
WorkingPath,
BundleExtensionRef,
}

/// <summary>
Expand Down Expand Up @@ -99,5 +101,11 @@ public string WorkingPath
get => (string)this.Fields[(int)WixBundleContainerSymbolFields.WorkingPath];
set => this.Set((int)WixBundleContainerSymbolFields.WorkingPath, value);
}

public string BundleExtensionRef
{
get => (string)this.Fields[(int)WixBundleContainerSymbolFields.BundleExtensionRef];
set => this.Set((int)WixBundleContainerSymbolFields.BundleExtensionRef, value);
}
}
}
6 changes: 6 additions & 0 deletions src/api/wix/WixToolset.Data/WarningMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,11 @@ public static Message VBScriptIsDeprecated(SourceLineNumber sourceLineNumbers)
return Message(sourceLineNumbers, Ids.VBScriptIsDeprecated, "VBScript is a deprecated Windows component: https://learn.microsoft.com/en-us/windows/whats-new/deprecated-features. VBScript custom actions might fail on some Windows systems. Rewrite or eliminate VBScript custom actions for best compatibility.");
}

public static Message MissingContainerExtension(SourceLineNumber sourceLineNumbers, string containerId, string bundleExtensionRef)
{
return Message(sourceLineNumbers, Ids.MissingContainerExtension, "Container '{0}' has BundleExtensionRef set to '{1}', which could not be resolved to a container extension. To extract this container add the missing extension to the extraction command line", containerId, bundleExtensionRef);
}

private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
{
return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args);
Expand Down Expand Up @@ -861,6 +866,7 @@ public enum Ids
ExePackageDetectInformationRecommended = 1161,
InvalidWixVersion = 1162,
VBScriptIsDeprecated = 1163,
MissingContainerExtension = 1164,
}
}
}
Loading
Loading