/*******************************************************************************
*
*  (C) COPYRIGHT AUTHORS, 2020 - 2026
*
*  TITLE:       FUSUTIL.H
*
*  VERSION:     3.70
*
*  DATE:        15 May 2026
*
*  Common header file for the Windows Fusion support routines.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
#pragma once

/*

Begin NETFX SDK rip to get rid of NETFX dependency

*/

/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif

/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif

#include "rpc.h"
#include "rpcndr.h"

#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__

#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

/* Forward Declarations */

#ifndef __IAssemblyCache_FWD_DEFINED__
#define __IAssemblyCache_FWD_DEFINED__
typedef interface IAssemblyCache IAssemblyCache;

#endif 	/* __IAssemblyCache_FWD_DEFINED__ */


#ifndef __IAssemblyCacheItem_FWD_DEFINED__
#define __IAssemblyCacheItem_FWD_DEFINED__
typedef interface IAssemblyCacheItem IAssemblyCacheItem;

#endif 	/* __IAssemblyCacheItem_FWD_DEFINED__ */


#ifndef __IAssemblyName_FWD_DEFINED__
#define __IAssemblyName_FWD_DEFINED__
typedef interface IAssemblyName IAssemblyName;

#endif 	/* __IAssemblyName_FWD_DEFINED__ */


#ifndef __IAssemblyEnum_FWD_DEFINED__
#define __IAssemblyEnum_FWD_DEFINED__
typedef interface IAssemblyEnum IAssemblyEnum;

#endif 	/* __IAssemblyEnum_FWD_DEFINED__ */

/* header files for imported files */
#include "objidl.h"

#ifdef __cplusplus
extern "C" {
#endif 


    /* interface __MIDL_itf_fusion_0000_0000 */
    /* [local] */


#ifdef _MSC_VER
#pragma comment(lib,"uuid.lib")
#endif

//---------------------------------------------------------------------------=
// Fusion Interfaces.

#ifdef _MSC_VER
#pragma once
#endif

    typedef /* [public] */
        enum __MIDL___MIDL_itf_fusion_0000_0000_0001
    {
        ASM_CACHE_ZAP = 0x1,
        ASM_CACHE_GAC = 0x2,
        ASM_CACHE_DOWNLOAD = 0x4,
        ASM_CACHE_ROOT = 0x8,
        ASM_CACHE_ROOT_EX = 0x80
    } 	ASM_CACHE_FLAGS;

#ifndef PEKIND_ENUM_DEFINED
#define PEKIND_ENUM_DEFINED
    typedef
        enum _tagPEKIND
    {
        peNone = 0,
        peMSIL = 0x1,
        peI386 = 0x2,
        peIA64 = 0x3,
        peAMD64 = 0x4,
        peARM = 0x5,
        peARM64 = 0x6,
        peInvalid = 0xffffffff
    } 	PEKIND;

#endif
    typedef
        enum _tagAssemblyContentType
    {
        AssemblyContentType_Default = 0,
        AssemblyContentType_WindowsRuntime = 0x1,
        AssemblyContentType_Invalid = 0xffffffff
    } 	AssemblyContentType;

    // {E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE}
    EXTERN_GUID(IID_IAssemblyCache, 0xE707DCDE, 0xD1CD, 0x11D2, 0xBA, 0xB9, 0x00, 0xC0, 0x4F, 0x8E, 0xCE, 0xAE);


    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0000_v0_0_c_ifspec;
    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0000_v0_0_s_ifspec;

#ifndef __IAssemblyCache_INTERFACE_DEFINED__
#define __IAssemblyCache_INTERFACE_DEFINED__

    /* interface IAssemblyCache */
    /* [unique][uuid][object][local] */

    // {8cedc215-ac4b-488b-93c0-a50a49cb2fb8}
    EXTERN_GUID(FUSION_REFCOUNT_UNINSTALL_SUBKEY_GUID, 0x8cedc215, 0xac4b, 0x488b, 0x93, 0xc0, 0xa5, 0x0a, 0x49, 0xcb, 0x2f, 0xb8);

    // {b02f9d65-fb77-4f7a-afa5-b391309f11c9}
    EXTERN_GUID(FUSION_REFCOUNT_FILEPATH_GUID, 0xb02f9d65, 0xfb77, 0x4f7a, 0xaf, 0xa5, 0xb3, 0x91, 0x30, 0x9f, 0x11, 0xc9);

    // {2ec93463-b0c3-45e1-8364-327e96aea856}
    EXTERN_GUID(FUSION_REFCOUNT_OPAQUE_STRING_GUID, 0x2ec93463, 0xb0c3, 0x45e1, 0x83, 0x64, 0x32, 0x7e, 0x96, 0xae, 0xa8, 0x56);
    // {25df0fc1-7f97-4070-add7-4b13bbfd7cb8} // this GUID cannot be used for installing into GAC.
    EXTERN_GUID(FUSION_REFCOUNT_MSI_GUID, 0x25df0fc1, 0x7f97, 0x4070, 0xad, 0xd7, 0x4b, 0x13, 0xbb, 0xfd, 0x7c, 0xb8);
    // {d16d444c-56d8-11d5-882d-0080c847b195}
    EXTERN_GUID(FUSION_REFCOUNT_OSINSTALL_GUID, 0xd16d444c, 0x56d8, 0x11d5, 0x88, 0x2d, 0x00, 0x80, 0xc8, 0x47, 0xb1, 0x95);
    typedef struct _FUSION_INSTALL_REFERENCE_
    {
        DWORD cbSize;
        DWORD dwFlags;
        GUID guidScheme;
        LPCWSTR szIdentifier;
        LPCWSTR szNonCannonicalData;
    } 	FUSION_INSTALL_REFERENCE;

    typedef struct _FUSION_INSTALL_REFERENCE_* LPFUSION_INSTALL_REFERENCE;

    typedef const FUSION_INSTALL_REFERENCE* LPCFUSION_INSTALL_REFERENCE;

    typedef struct _ASSEMBLY_INFO
    {
        ULONG cbAssemblyInfo;
        DWORD dwAssemblyFlags;
        ULARGE_INTEGER uliAssemblySizeInKB;
        LPWSTR pszCurrentAssemblyPathBuf;
        ULONG cchBuf;
    } 	ASSEMBLY_INFO;

#define IASSEMBLYCACHE_INSTALL_FLAG_REFRESH       (0x00000001)
#define IASSEMBLYCACHE_INSTALL_FLAG_FORCE_REFRESH (0x00000002)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED (1)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_STILL_IN_USE (2)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED (3)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_DELETE_PENDING (4)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_HAS_INSTALL_REFERENCES (5)
#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_REFERENCE_NOT_FOUND (6)
#define QUERYASMINFO_FLAG_VALIDATE        (0x00000001)
#define QUERYASMINFO_FLAG_GETSIZE         (0x00000002)
#define ASSEMBLYINFO_FLAG_INSTALLED       (0x00000001)
#define ASSEMBLYINFO_FLAG_PAYLOADRESIDENT (0x00000002)

    EXTERN_C const IID IID_IAssemblyCache;

#if defined(__cplusplus) && !defined(CINTERFACE)

    MIDL_INTERFACE("e707dcde-d1cd-11d2-bab9-00c04f8eceae")
        IAssemblyCache : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE UninstallAssembly(
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszAssemblyName,
            /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData,
            /* [optional][out] */ ULONG * pulDisposition) = 0;

        virtual HRESULT STDMETHODCALLTYPE QueryAssemblyInfo(
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszAssemblyName,
            /* [out][in] */ ASSEMBLY_INFO* pAsmInfo) = 0;

        virtual HRESULT STDMETHODCALLTYPE CreateAssemblyCacheItem(
            /* [in] */ DWORD dwFlags,
            /* [in] */ PVOID pvReserved,
            /* [out] */ IAssemblyCacheItem** ppAsmItem,
            /* [optional][in] */ LPCWSTR pszAssemblyName) = 0;

        virtual HRESULT STDMETHODCALLTYPE CreateAssemblyScavenger(
            /* [out] */ IUnknown** ppUnkReserved) = 0;

        virtual HRESULT STDMETHODCALLTYPE InstallAssembly(
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszManifestFilePath,
            /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData) = 0;

    };


#else 	/* C style interface */

    typedef struct IAssemblyCacheVtbl
    {
        BEGIN_INTERFACE

            HRESULT(STDMETHODCALLTYPE* QueryInterface)(
                IAssemblyCache* This,
                /* [in] */ REFIID riid,
                /* [annotation][iid_is][out] */
                _COM_Outptr_  void** ppvObject);

        ULONG(STDMETHODCALLTYPE* AddRef)(
            IAssemblyCache* This);

        ULONG(STDMETHODCALLTYPE* Release)(
            IAssemblyCache* This);

        HRESULT(STDMETHODCALLTYPE* UninstallAssembly)(
            IAssemblyCache* This,
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszAssemblyName,
            /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData,
            /* [optional][out] */ ULONG* pulDisposition);

        HRESULT(STDMETHODCALLTYPE* QueryAssemblyInfo)(
            IAssemblyCache* This,
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszAssemblyName,
            /* [out][in] */ ASSEMBLY_INFO* pAsmInfo);

        HRESULT(STDMETHODCALLTYPE* CreateAssemblyCacheItem)(
            IAssemblyCache* This,
            /* [in] */ DWORD dwFlags,
            /* [in] */ PVOID pvReserved,
            /* [out] */ IAssemblyCacheItem** ppAsmItem,
            /* [optional][in] */ LPCWSTR pszAssemblyName);

        HRESULT(STDMETHODCALLTYPE* CreateAssemblyScavenger)(
            IAssemblyCache* This,
            /* [out] */ IUnknown** ppUnkReserved);

        HRESULT(STDMETHODCALLTYPE* InstallAssembly)(
            IAssemblyCache* This,
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszManifestFilePath,
            /* [in] */ LPCFUSION_INSTALL_REFERENCE pRefData);

        END_INTERFACE
    } IAssemblyCacheVtbl;

    interface IAssemblyCache
    {
        CONST_VTBL struct IAssemblyCacheVtbl* lpVtbl;
    };

#ifdef COBJMACROS

#define IAssemblyCache_QueryInterface(This,riid,ppvObject)	\
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

#define IAssemblyCache_AddRef(This)	\
    ( (This)->lpVtbl -> AddRef(This) ) 

#define IAssemblyCache_Release(This)	\
    ( (This)->lpVtbl -> Release(This) ) 


#define IAssemblyCache_UninstallAssembly(This,dwFlags,pszAssemblyName,pRefData,pulDisposition)	\
    ( (This)->lpVtbl -> UninstallAssembly(This,dwFlags,pszAssemblyName,pRefData,pulDisposition) ) 

#define IAssemblyCache_QueryAssemblyInfo(This,dwFlags,pszAssemblyName,pAsmInfo)	\
    ( (This)->lpVtbl -> QueryAssemblyInfo(This,dwFlags,pszAssemblyName,pAsmInfo) ) 

#define IAssemblyCache_CreateAssemblyCacheItem(This,dwFlags,pvReserved,ppAsmItem,pszAssemblyName)	\
    ( (This)->lpVtbl -> CreateAssemblyCacheItem(This,dwFlags,pvReserved,ppAsmItem,pszAssemblyName) ) 

#define IAssemblyCache_CreateAssemblyScavenger(This,ppUnkReserved)	\
    ( (This)->lpVtbl -> CreateAssemblyScavenger(This,ppUnkReserved) ) 

#define IAssemblyCache_InstallAssembly(This,dwFlags,pszManifestFilePath,pRefData)	\
    ( (This)->lpVtbl -> InstallAssembly(This,dwFlags,pszManifestFilePath,pRefData) ) 

#endif /* COBJMACROS */


#endif 	/* C style interface */

#endif 	/* __IAssemblyCache_INTERFACE_DEFINED__ */


    /* interface __MIDL_itf_fusion_0000_0001 */
    /* [local] */

    // {9e3aaeb4-d1cd-11d2-bab9-00c04f8eceae}
    EXTERN_GUID(IID_IAssemblyCacheItem, 0x9e3aaeb4, 0xd1cd, 0x11d2, 0xba, 0xb9, 0x00, 0xc0, 0x4f, 0x8e, 0xce, 0xae);

    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0001_v0_0_c_ifspec;
    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0001_v0_0_s_ifspec;

#ifndef __IAssemblyCacheItem_INTERFACE_DEFINED__
#define __IAssemblyCacheItem_INTERFACE_DEFINED__

    /* interface IAssemblyCacheItem */
    /* [unique][uuid][object][local] */

#define STREAM_FORMAT_COMPLIB_MODULE    0
#define STREAM_FORMAT_COMPLIB_MANIFEST  1
#define STREAM_FORMAT_WIN32_MODULE      2
#define STREAM_FORMAT_WIN32_MANIFEST    4
#define IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH       (0x00000001)
#define IASSEMBLYCACHEITEM_COMMIT_FLAG_FORCE_REFRESH (0x00000002)
#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_INSTALLED (1)
#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_REFRESHED (2)
#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_ALREADY_INSTALLED (3)

    EXTERN_C const IID IID_IAssemblyCacheItem;

#if defined(__cplusplus) && !defined(CINTERFACE)

    MIDL_INTERFACE("9e3aaeb4-d1cd-11d2-bab9-00c04f8eceae")
        IAssemblyCacheItem : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE CreateStream(
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszStreamName,
            /* [in] */ DWORD dwFormat,
            /* [in] */ DWORD dwFormatFlags,
            /* [out] */ IStream * *ppIStream,
            /* [optional][in] */ ULARGE_INTEGER * puliMaxSize) = 0;

        virtual HRESULT STDMETHODCALLTYPE Commit(
            /* [in] */ DWORD dwFlags,
            /* [optional][out] */ ULONG* pulDisposition) = 0;

        virtual HRESULT STDMETHODCALLTYPE AbortItem(void) = 0;

    };


#else 	/* C style interface */

    typedef struct IAssemblyCacheItemVtbl
    {
        BEGIN_INTERFACE

            HRESULT(STDMETHODCALLTYPE* QueryInterface)(
                IAssemblyCacheItem* This,
                /* [in] */ REFIID riid,
                /* [annotation][iid_is][out] */
                _COM_Outptr_  void** ppvObject);

        ULONG(STDMETHODCALLTYPE* AddRef)(
            IAssemblyCacheItem* This);

        ULONG(STDMETHODCALLTYPE* Release)(
            IAssemblyCacheItem* This);

        HRESULT(STDMETHODCALLTYPE* CreateStream)(
            IAssemblyCacheItem* This,
            /* [in] */ DWORD dwFlags,
            /* [in] */ LPCWSTR pszStreamName,
            /* [in] */ DWORD dwFormat,
            /* [in] */ DWORD dwFormatFlags,
            /* [out] */ IStream** ppIStream,
            /* [optional][in] */ ULARGE_INTEGER* puliMaxSize);

        HRESULT(STDMETHODCALLTYPE* Commit)(
            IAssemblyCacheItem* This,
            /* [in] */ DWORD dwFlags,
            /* [optional][out] */ ULONG* pulDisposition);

        HRESULT(STDMETHODCALLTYPE* AbortItem)(
            IAssemblyCacheItem* This);

        END_INTERFACE
    } IAssemblyCacheItemVtbl;

    interface IAssemblyCacheItem
    {
        CONST_VTBL struct IAssemblyCacheItemVtbl* lpVtbl;
    };

#ifdef COBJMACROS

#define IAssemblyCacheItem_QueryInterface(This,riid,ppvObject)	\
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

#define IAssemblyCacheItem_AddRef(This)	\
    ( (This)->lpVtbl -> AddRef(This) ) 

#define IAssemblyCacheItem_Release(This)	\
    ( (This)->lpVtbl -> Release(This) ) 


#define IAssemblyCacheItem_CreateStream(This,dwFlags,pszStreamName,dwFormat,dwFormatFlags,ppIStream,puliMaxSize)	\
    ( (This)->lpVtbl -> CreateStream(This,dwFlags,pszStreamName,dwFormat,dwFormatFlags,ppIStream,puliMaxSize) ) 

#define IAssemblyCacheItem_Commit(This,dwFlags,pulDisposition)	\
    ( (This)->lpVtbl -> Commit(This,dwFlags,pulDisposition) ) 

#define IAssemblyCacheItem_AbortItem(This)	\
    ( (This)->lpVtbl -> AbortItem(This) ) 

#endif /* COBJMACROS */

#endif 	/* C style interface */

#endif 	/* __IAssemblyCacheItem_INTERFACE_DEFINED__ */

    /* interface __MIDL_itf_fusion_0000_0002 */
    /* [local] */

    // {CD193BC0-B4BC-11d2-9833-00C04FC31D2E}
    EXTERN_GUID(IID_IAssemblyName, 0xCD193BC0, 0xB4BC, 0x11d2, 0x98, 0x33, 0x00, 0xC0, 0x4F, 0xC3, 0x1D, 0x2E);


    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0002_v0_0_c_ifspec;
    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0002_v0_0_s_ifspec;

#ifndef __IAssemblyName_INTERFACE_DEFINED__
#define __IAssemblyName_INTERFACE_DEFINED__

    /* interface IAssemblyName */
    /* [unique][uuid][object][local] */

    typedef /* [unique] */ IAssemblyName* LPASSEMBLYNAME;

    typedef /* [public] */
        enum __MIDL_IAssemblyName_0001
    {
        CANOF_PARSE_DISPLAY_NAME = 0x1,
        CANOF_SET_DEFAULT_VALUES = 0x2,
        CANOF_VERIFY_FRIEND_ASSEMBLYNAME = 0x4,
        CANOF_PARSE_FRIEND_DISPLAY_NAME = (CANOF_PARSE_DISPLAY_NAME | CANOF_VERIFY_FRIEND_ASSEMBLYNAME)
    } 	CREATE_ASM_NAME_OBJ_FLAGS;

    typedef /* [public] */
        enum __MIDL_IAssemblyName_0002
    {
        ASM_NAME_PUBLIC_KEY = 0,
        ASM_NAME_PUBLIC_KEY_TOKEN = (ASM_NAME_PUBLIC_KEY + 1),
        ASM_NAME_HASH_VALUE = (ASM_NAME_PUBLIC_KEY_TOKEN + 1),
        ASM_NAME_NAME = (ASM_NAME_HASH_VALUE + 1),
        ASM_NAME_MAJOR_VERSION = (ASM_NAME_NAME + 1),
        ASM_NAME_MINOR_VERSION = (ASM_NAME_MAJOR_VERSION + 1),
        ASM_NAME_BUILD_NUMBER = (ASM_NAME_MINOR_VERSION + 1),
        ASM_NAME_REVISION_NUMBER = (ASM_NAME_BUILD_NUMBER + 1),
        ASM_NAME_CULTURE = (ASM_NAME_REVISION_NUMBER + 1),
        ASM_NAME_PROCESSOR_ID_ARRAY = (ASM_NAME_CULTURE + 1),
        ASM_NAME_OSINFO_ARRAY = (ASM_NAME_PROCESSOR_ID_ARRAY + 1),
        ASM_NAME_HASH_ALGID = (ASM_NAME_OSINFO_ARRAY + 1),
        ASM_NAME_ALIAS = (ASM_NAME_HASH_ALGID + 1),
        ASM_NAME_CODEBASE_URL = (ASM_NAME_ALIAS + 1),
        ASM_NAME_CODEBASE_LASTMOD = (ASM_NAME_CODEBASE_URL + 1),
        ASM_NAME_NULL_PUBLIC_KEY = (ASM_NAME_CODEBASE_LASTMOD + 1),
        ASM_NAME_NULL_PUBLIC_KEY_TOKEN = (ASM_NAME_NULL_PUBLIC_KEY + 1),
        ASM_NAME_CUSTOM = (ASM_NAME_NULL_PUBLIC_KEY_TOKEN + 1),
        ASM_NAME_NULL_CUSTOM = (ASM_NAME_CUSTOM + 1),
        ASM_NAME_MVID = (ASM_NAME_NULL_CUSTOM + 1),
        ASM_NAME_FILE_MAJOR_VERSION = (ASM_NAME_MVID + 1),
        ASM_NAME_FILE_MINOR_VERSION = (ASM_NAME_FILE_MAJOR_VERSION + 1),
        ASM_NAME_FILE_BUILD_NUMBER = (ASM_NAME_FILE_MINOR_VERSION + 1),
        ASM_NAME_FILE_REVISION_NUMBER = (ASM_NAME_FILE_BUILD_NUMBER + 1),
        ASM_NAME_RETARGET = (ASM_NAME_FILE_REVISION_NUMBER + 1),
        ASM_NAME_SIGNATURE_BLOB = (ASM_NAME_RETARGET + 1),
        ASM_NAME_CONFIG_MASK = (ASM_NAME_SIGNATURE_BLOB + 1),
        ASM_NAME_ARCHITECTURE = (ASM_NAME_CONFIG_MASK + 1),
        ASM_NAME_CONTENT_TYPE = (ASM_NAME_ARCHITECTURE + 1),
        ASM_NAME_MAX_PARAMS = (ASM_NAME_CONTENT_TYPE + 1)
    } 	ASM_NAME;

    typedef /* [public] */
        enum __MIDL_IAssemblyName_0003
    {
        ASM_DISPLAYF_VERSION = 0x1,
        ASM_DISPLAYF_CULTURE = 0x2,
        ASM_DISPLAYF_PUBLIC_KEY_TOKEN = 0x4,
        ASM_DISPLAYF_PUBLIC_KEY = 0x8,
        ASM_DISPLAYF_CUSTOM = 0x10,
        ASM_DISPLAYF_PROCESSORARCHITECTURE = 0x20,
        ASM_DISPLAYF_LANGUAGEID = 0x40,
        ASM_DISPLAYF_RETARGET = 0x80,
        ASM_DISPLAYF_CONFIG_MASK = 0x100,
        ASM_DISPLAYF_MVID = 0x200,
        ASM_DISPLAYF_CONTENT_TYPE = 0x400,
        ASM_DISPLAYF_FULL = (((((ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE) | ASM_DISPLAYF_PUBLIC_KEY_TOKEN) | ASM_DISPLAYF_RETARGET) | ASM_DISPLAYF_PROCESSORARCHITECTURE) | ASM_DISPLAYF_CONTENT_TYPE)
    } 	ASM_DISPLAY_FLAGS;

    typedef /* [public] */
        enum __MIDL_IAssemblyName_0004
    {
        ASM_CMPF_NAME = 0x1,
        ASM_CMPF_MAJOR_VERSION = 0x2,
        ASM_CMPF_MINOR_VERSION = 0x4,
        ASM_CMPF_BUILD_NUMBER = 0x8,
        ASM_CMPF_REVISION_NUMBER = 0x10,
        ASM_CMPF_VERSION = (((ASM_CMPF_MAJOR_VERSION | ASM_CMPF_MINOR_VERSION) | ASM_CMPF_BUILD_NUMBER) | ASM_CMPF_REVISION_NUMBER),
        ASM_CMPF_PUBLIC_KEY_TOKEN = 0x20,
        ASM_CMPF_CULTURE = 0x40,
        ASM_CMPF_CUSTOM = 0x80,
        ASM_CMPF_DEFAULT = 0x100,
        ASM_CMPF_RETARGET = 0x200,
        ASM_CMPF_ARCHITECTURE = 0x400,
        ASM_CMPF_CONFIG_MASK = 0x800,
        ASM_CMPF_MVID = 0x1000,
        ASM_CMPF_SIGNATURE = 0x2000,
        ASM_CMPF_CONTENT_TYPE = 0x4000,
        ASM_CMPF_IL_ALL = (((ASM_CMPF_NAME | ASM_CMPF_VERSION) | ASM_CMPF_PUBLIC_KEY_TOKEN) | ASM_CMPF_CULTURE),
        ASM_CMPF_IL_NO_VERSION = ((ASM_CMPF_NAME | ASM_CMPF_PUBLIC_KEY_TOKEN) | ASM_CMPF_CULTURE)
    } 	ASM_CMP_FLAGS;


    EXTERN_C const IID IID_IAssemblyName;

#if defined(__cplusplus) && !defined(CINTERFACE)

    MIDL_INTERFACE("CD193BC0-B4BC-11d2-9833-00C04FC31D2E")
        IAssemblyName : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE SetProperty(
            /* [in] */ DWORD PropertyId,
            /* [in] */ const void* pvProperty,
            /* [in] */ DWORD cbProperty) = 0;

        virtual HRESULT STDMETHODCALLTYPE GetProperty(
            /* [in] */ DWORD PropertyId,
            /* [out] */ LPVOID pvProperty,
            /* [out][in] */ LPDWORD pcbProperty) = 0;

        virtual HRESULT STDMETHODCALLTYPE Finalize(void) = 0;

        virtual HRESULT STDMETHODCALLTYPE GetDisplayName(
            /* [annotation][out] */
            _Out_writes_opt_(*pccDisplayName)  LPOLESTR szDisplayName,
            /* [out][in] */ LPDWORD pccDisplayName,
            /* [in] */ DWORD dwDisplayFlags) = 0;

        virtual HRESULT STDMETHODCALLTYPE Reserved(
            /* [in] */ REFIID refIID,
            /* [in] */ IUnknown* pUnkReserved1,
            /* [in] */ IUnknown* pUnkReserved2,
            /* [in] */ LPCOLESTR szReserved,
            /* [in] */ LONGLONG llReserved,
            /* [in] */ LPVOID pvReserved,
            /* [in] */ DWORD cbReserved,
            /* [out] */ LPVOID* ppReserved) = 0;

        virtual HRESULT STDMETHODCALLTYPE GetName(
            /* [annotation][out][in] */
            _Inout_  LPDWORD lpcwBuffer,
            /* [annotation][out] */
            _Out_writes_opt_(*lpcwBuffer)  WCHAR* pwzName) = 0;

        virtual HRESULT STDMETHODCALLTYPE GetVersion(
            /* [out] */ LPDWORD pdwVersionHi,
            /* [out] */ LPDWORD pdwVersionLow) = 0;

        virtual HRESULT STDMETHODCALLTYPE IsEqual(
            /* [in] */ IAssemblyName* pName,
            /* [in] */ DWORD dwCmpFlags) = 0;

        virtual HRESULT STDMETHODCALLTYPE Clone(
            /* [out] */ IAssemblyName** pName) = 0;

    };


#else 	/* C style interface */

    typedef struct IAssemblyNameVtbl
    {
        BEGIN_INTERFACE

            HRESULT(STDMETHODCALLTYPE* QueryInterface)(
                IAssemblyName* This,
                /* [in] */ REFIID riid,
                /* [annotation][iid_is][out] */
                _COM_Outptr_  void** ppvObject);

        ULONG(STDMETHODCALLTYPE* AddRef)(
            IAssemblyName* This);

        ULONG(STDMETHODCALLTYPE* Release)(
            IAssemblyName* This);

        HRESULT(STDMETHODCALLTYPE* SetProperty)(
            IAssemblyName* This,
            /* [in] */ DWORD PropertyId,
            /* [in] */ const void* pvProperty,
            /* [in] */ DWORD cbProperty);

        HRESULT(STDMETHODCALLTYPE* GetProperty)(
            IAssemblyName* This,
            /* [in] */ DWORD PropertyId,
            /* [out] */ LPVOID pvProperty,
            /* [out][in] */ LPDWORD pcbProperty);

        HRESULT(STDMETHODCALLTYPE* Finalize)(
            IAssemblyName* This);

        HRESULT(STDMETHODCALLTYPE* GetDisplayName)(
            IAssemblyName* This,
            /* [annotation][out] */
            _Out_writes_opt_(*pccDisplayName)  LPOLESTR szDisplayName,
            /* [out][in] */ LPDWORD pccDisplayName,
            /* [in] */ DWORD dwDisplayFlags);

        HRESULT(STDMETHODCALLTYPE* Reserved)(
            IAssemblyName* This,
            /* [in] */ REFIID refIID,
            /* [in] */ IUnknown* pUnkReserved1,
            /* [in] */ IUnknown* pUnkReserved2,
            /* [in] */ LPCOLESTR szReserved,
            /* [in] */ LONGLONG llReserved,
            /* [in] */ LPVOID pvReserved,
            /* [in] */ DWORD cbReserved,
            /* [out] */ LPVOID* ppReserved);

        HRESULT(STDMETHODCALLTYPE* GetName)(
            IAssemblyName* This,
            /* [annotation][out][in] */
            _Inout_  LPDWORD lpcwBuffer,
            /* [annotation][out] */
            _Out_writes_opt_(*lpcwBuffer)  WCHAR* pwzName);

        HRESULT(STDMETHODCALLTYPE* GetVersion)(
            IAssemblyName* This,
            /* [out] */ LPDWORD pdwVersionHi,
            /* [out] */ LPDWORD pdwVersionLow);

        HRESULT(STDMETHODCALLTYPE* IsEqual)(
            IAssemblyName* This,
            /* [in] */ IAssemblyName* pName,
            /* [in] */ DWORD dwCmpFlags);

        HRESULT(STDMETHODCALLTYPE* Clone)(
            IAssemblyName* This,
            /* [out] */ IAssemblyName** pName);

        END_INTERFACE
    } IAssemblyNameVtbl;

    interface IAssemblyName
    {
        CONST_VTBL struct IAssemblyNameVtbl* lpVtbl;
    };

#ifdef COBJMACROS

#define IAssemblyName_QueryInterface(This,riid,ppvObject)	\
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

#define IAssemblyName_AddRef(This)	\
    ( (This)->lpVtbl -> AddRef(This) ) 

#define IAssemblyName_Release(This)	\
    ( (This)->lpVtbl -> Release(This) ) 

#define IAssemblyName_SetProperty(This,PropertyId,pvProperty,cbProperty)	\
    ( (This)->lpVtbl -> SetProperty(This,PropertyId,pvProperty,cbProperty) ) 

#define IAssemblyName_GetProperty(This,PropertyId,pvProperty,pcbProperty)	\
    ( (This)->lpVtbl -> GetProperty(This,PropertyId,pvProperty,pcbProperty) ) 

#define IAssemblyName_Finalize(This)	\
    ( (This)->lpVtbl -> Finalize(This) ) 

#define IAssemblyName_GetDisplayName(This,szDisplayName,pccDisplayName,dwDisplayFlags)	\
    ( (This)->lpVtbl -> GetDisplayName(This,szDisplayName,pccDisplayName,dwDisplayFlags) ) 

#define IAssemblyName_Reserved(This,refIID,pUnkReserved1,pUnkReserved2,szReserved,llReserved,pvReserved,cbReserved,ppReserved)	\
    ( (This)->lpVtbl -> Reserved(This,refIID,pUnkReserved1,pUnkReserved2,szReserved,llReserved,pvReserved,cbReserved,ppReserved) ) 

#define IAssemblyName_GetName(This,lpcwBuffer,pwzName)	\
    ( (This)->lpVtbl -> GetName(This,lpcwBuffer,pwzName) ) 

#define IAssemblyName_GetVersion(This,pdwVersionHi,pdwVersionLow)	\
    ( (This)->lpVtbl -> GetVersion(This,pdwVersionHi,pdwVersionLow) ) 

#define IAssemblyName_IsEqual(This,pName,dwCmpFlags)	\
    ( (This)->lpVtbl -> IsEqual(This,pName,dwCmpFlags) ) 

#define IAssemblyName_Clone(This,pName)	\
    ( (This)->lpVtbl -> Clone(This,pName) ) 

#endif /* COBJMACROS */

#endif 	/* C style interface */


#endif 	/* __IAssemblyName_INTERFACE_DEFINED__ */

    /* interface __MIDL_itf_fusion_0000_0003 */
    /* [local] */

    // {21B8916C-F28E-11D2-A473-00C04F8EF448}
    EXTERN_GUID(IID_IAssemblyEnum, 0x21B8916C, 0xF28E, 0x11D2, 0xA4, 0x73, 0x00, 0xC0, 0x4F, 0x8E, 0xF4, 0x48);


    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0003_v0_0_c_ifspec;
    extern RPC_IF_HANDLE __MIDL_itf_fusion_0000_0003_v0_0_s_ifspec;

#ifndef __IAssemblyEnum_INTERFACE_DEFINED__
#define __IAssemblyEnum_INTERFACE_DEFINED__

    /* interface IAssemblyEnum */
    /* [unique][uuid][object][local] */

    EXTERN_C const IID IID_IAssemblyEnum;

#if defined(__cplusplus) && !defined(CINTERFACE)

    MIDL_INTERFACE("21b8916c-f28e-11d2-a473-00c04f8ef448")
        IAssemblyEnum : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetNextAssembly(
            /* [in] */ LPVOID pvReserved,
            /* [out] */ IAssemblyName * *ppName,
            /* [in] */ DWORD dwFlags) = 0;

        virtual HRESULT STDMETHODCALLTYPE Reset(void) = 0;

        virtual HRESULT STDMETHODCALLTYPE Clone(
            /* [out] */ IAssemblyEnum** ppEnum) = 0;

    };


#else 	/* C style interface */

    typedef struct IAssemblyEnumVtbl
    {
        BEGIN_INTERFACE

            HRESULT(STDMETHODCALLTYPE* QueryInterface)(
                IAssemblyEnum* This,
                /* [in] */ REFIID riid,
                /* [annotation][iid_is][out] */
                _COM_Outptr_  void** ppvObject);

        ULONG(STDMETHODCALLTYPE* AddRef)(
            IAssemblyEnum* This);

        ULONG(STDMETHODCALLTYPE* Release)(
            IAssemblyEnum* This);

        HRESULT(STDMETHODCALLTYPE* GetNextAssembly)(
            IAssemblyEnum* This,
            /* [in] */ LPVOID pvReserved,
            /* [out] */ IAssemblyName** ppName,
            /* [in] */ DWORD dwFlags);

        HRESULT(STDMETHODCALLTYPE* Reset)(
            IAssemblyEnum* This);

        HRESULT(STDMETHODCALLTYPE* Clone)(
            IAssemblyEnum* This,
            /* [out] */ IAssemblyEnum** ppEnum);

        END_INTERFACE
    } IAssemblyEnumVtbl;

    interface IAssemblyEnum
    {
        CONST_VTBL struct IAssemblyEnumVtbl* lpVtbl;
    };

#ifdef COBJMACROS

#define IAssemblyEnum_QueryInterface(This,riid,ppvObject)	\
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

#define IAssemblyEnum_AddRef(This)	\
    ( (This)->lpVtbl -> AddRef(This) ) 

#define IAssemblyEnum_Release(This)	\
    ( (This)->lpVtbl -> Release(This) ) 


#define IAssemblyEnum_GetNextAssembly(This,pvReserved,ppName,dwFlags)	\
    ( (This)->lpVtbl -> GetNextAssembly(This,pvReserved,ppName,dwFlags) ) 

#define IAssemblyEnum_Reset(This)	\
    ( (This)->lpVtbl -> Reset(This) ) 

#define IAssemblyEnum_Clone(This,ppEnum)	\
    ( (This)->lpVtbl -> Clone(This,ppEnum) ) 

#endif /* COBJMACROS */

#endif 	/* C style interface */

#endif 	/* __IAssemblyEnum_INTERFACE_DEFINED__ */

/*

 End of NETFX SDK rip

*/

//
// Fusion CLI metadata structures
//
typedef struct _STORAGESIGNATURE {
    ULONG lSignature;               // "Magic" signature.
    USHORT iMajorVer;               // Major file version.
    USHORT iMinorVer;               // Minor file version.
    ULONG iExtraData;               // Offset to next structure of information 
    ULONG iVersionString;           // Length of version string
    BYTE pVersion[ANYSIZE_ARRAY];   // Version string
} STORAGESIGNATURE, * PSTORAGESIGNATURE;

typedef struct _STORAGEHEADER {
    BYTE fFlags; // STGHDR_xxx flags.
    BYTE pad;
    USHORT iStreams; // How many streams are there.
} STORAGEHEADER, * PSTORAGEHEADER;

#define MAXSTREAMNAME 32

typedef struct _STORAGESTREAM {
    ULONG iOffset;                // Offset in file for this stream.
    ULONG iSize;                  // Size of the file.
    CHAR  rcName[MAXSTREAMNAME];
} STORAGESTREAM, * PSTORAGESTREAM;

#include <pshpack1.h>
typedef struct _STORAGETABLESHEADER {
    DWORD Reserved0;
    BYTE MajorVersion;
    BYTE MinorVersion;
    BYTE HeapOffsetSizes;
    BYTE Reserved1;
    ULARGE_INTEGER Valid;
    ULARGE_INTEGER Sorted;
    ULONG Rows[ANYSIZE_ARRAY];
} STORAGETABLESHEADER, * PSTORAGETABLESHEADER;
#include <poppack.h>

#define STORAGE_MAGIC_SIG   0x424A5342  // BSJB

#define MD_STRINGS_BIT 0x1
#define MD_GUIDS_BIT   0x2
#define MD_BLOBS_BIT   0x4
#define MAX_CLR_TABLES  64

//
// Fusion metadata end
//

//
// Assembly cache scan routine and definitions.
//
typedef HRESULT(WINAPI* pfnCreateAssemblyEnum)(
    _Out_ IAssemblyEnum** pEnum,
    _In_opt_  IUnknown* pUnkReserved,
    _In_opt_  IAssemblyName* pName,
    _In_  DWORD dwFlags,
    _Reserved_  LPVOID pvReserved);

typedef HRESULT(WINAPI* pfnCreateAssemblyCache)(
    _Out_ IAssemblyCache** ppAsmCache,
    _In_  DWORD            dwReserved);

typedef struct _FUSION_SCAN_PARAM {
    _In_ GUID* ReferenceMVID;
    _Out_ LPWSTR lpFileName;
} FUSION_SCAN_PARAM, * PFUSION_SCAN_PARAM;

typedef BOOL(CALLBACK* pfnFusionScanFilesCallback)(
    LPWSTR CurrentDirectory,
    WIN32_FIND_DATA* FindData,
    PVOID UserContext);

typedef struct _UACME_FUSION_CONTEXT {
    BOOL Initialized;
    HINSTANCE hFusion;
    pfnCreateAssemblyCache CreateAssemblyCache;
    pfnCreateAssemblyEnum CreateAssemblyEnum;
} UACME_FUSION_CONTEXT, * PUACME_FUSION_CONTEXT;

BOOLEAN fusUtilInitFusion(
    _In_ DWORD dwVersion);

VOID fusUtilBinToUnicodeHex(
    _In_ const BYTE* pSrc,
    _In_ UINT cSrc,
    _Out_cap_(2 * cSrc + 1) LPWSTR pDst);

HRESULT fusUtilGetAssemblyName(
    _In_ IAssemblyName* pInterface,
    _Inout_ LPWSTR* lpName,
    _Out_opt_ PSIZE_T pcchName,
    _Inout_opt_ LPWSTR* lpDisplayName,
    _Out_opt_ PSIZE_T pcchDisplayName);

BOOL fusUtilGetAssemblyMVIDFromZapCache(
    _In_ LPCWSTR AssemblyName,
    _Inout_ GUID* ModuleVersionId);

HRESULT fusUtilGetAssemblyPath(
    _In_ IAssemblyCache* pInterface,
    _In_ LPCWSTR lpAssemblyName,
    _Inout_ LPCWSTR* lpAssemblyPath);

BOOLEAN fusUtilGetAssemblyPathByName(
    _In_ LPWSTR lpAssemblyName,
    _Inout_ LPWSTR* lpAssemblyPath);

BOOL fusUtilReferenceStreamByName(
    _In_ STORAGEHEADER* StorageHeader,
    _In_ LPCSTR StreamName,
    _Out_ PSTORAGESTREAM* StreamRef);

BOOL fusUtilGetImageMVID(
    _In_ LPCWSTR lpImageName,
    _Out_ GUID* ModuleVersionId);

BOOL fusUtilFindFileByMVIDCallback(
    _In_ LPWSTR CurrentDirectory,
    _In_ WIN32_FIND_DATA* FindData,
    _In_ PVOID UserContext);

BOOL fusUtilScanDirectory(
    _In_ LPWSTR lpDirectory,
    _In_ LPWSTR lpExtension,
    _In_ pfnFusionScanFilesCallback pfnCallback,
    _In_opt_ PVOID pvUserContext);

VOID fusUtilCombineNativeImageCacheName(
    _In_ LPCWSTR lpAssemblyName,
    _Inout_ LPWSTR lpNativeImageName,
    _In_ DWORD cchNativeName,
    _In_ BOOLEAN fIsAux);
