Fake Visual Studio being installed for EazFuscator for .NET5 and up obfuscation (in progress)
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
101
VisualStudioMock/ComProxy.cs
Normal file
101
VisualStudioMock/ComProxy.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
delegate int GetInterfaceDelegate(IntPtr @this, [MarshalAs(UnmanagedType.LPStruct)] Guid iid, out IntPtr ppv);
|
||||
delegate int AddRefDelegate(IntPtr @this);
|
||||
delegate int ReleaseDelegate(IntPtr @this);
|
||||
|
||||
sealed class ComProxy
|
||||
{
|
||||
private const int S_OK = 0;
|
||||
private const int E_NOINTERFACE = -2147467262;
|
||||
|
||||
private static readonly Guid IID_IUnknown = new Guid("00000000-0000-0000-c000-000000000046");
|
||||
private static readonly Guid IID_IManagedObject = new Guid("C3FCC19E-A970-11D2-8B5A-00A0C9B7C9C4");
|
||||
|
||||
private readonly object _realInstance;
|
||||
private readonly IntPtr _realInstanceN;
|
||||
private readonly IntPtr _proxyInstanceN;
|
||||
private readonly GetInterfaceDelegate _getInterface;
|
||||
private readonly IntPtr _getInterfaceN;
|
||||
private readonly AddRefDelegate _addRef;
|
||||
private readonly ReleaseDelegate _release;
|
||||
|
||||
internal ComProxy(object instance)
|
||||
{
|
||||
this._realInstance = instance;
|
||||
this._realInstanceN = Marshal.GetIUnknownForObject(instance);
|
||||
this._proxyInstanceN = Marshal.AllocHGlobal(IntPtr.Size * 4);
|
||||
|
||||
IntPtr vtbl = _proxyInstanceN + IntPtr.Size;
|
||||
Marshal.WriteIntPtr(_proxyInstanceN, vtbl);
|
||||
Marshal.WriteIntPtr(vtbl, this._getInterfaceN = Marshal.GetFunctionPointerForDelegate((Delegate)(this._getInterface = new GetInterfaceDelegate(GetInterface))));
|
||||
Marshal.WriteIntPtr(vtbl, IntPtr.Size * 1, Marshal.GetFunctionPointerForDelegate((Delegate)(this._addRef = new AddRefDelegate(AddRef))));
|
||||
Marshal.WriteIntPtr(vtbl, IntPtr.Size * 2, Marshal.GetFunctionPointerForDelegate((Delegate)(this._release = new ReleaseDelegate(Release))));
|
||||
}
|
||||
|
||||
internal object GetIUnknown()
|
||||
{
|
||||
return Marshal.GetObjectForIUnknown(_proxyInstanceN);
|
||||
}
|
||||
|
||||
private int GetInterface(IntPtr @this, [MarshalAs(UnmanagedType.LPStruct)] Guid iid, out IntPtr ppv)
|
||||
{
|
||||
if (iid == IID_IUnknown)
|
||||
{
|
||||
ppv = _proxyInstanceN;
|
||||
Ext.LogCall(_realInstance.GetType().Name, nameof(GetInterface), "IUnknown OK");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (iid == IID_IManagedObject)
|
||||
{
|
||||
ppv = IntPtr.Zero;
|
||||
Ext.LogCall(_realInstance.GetType().Name, nameof(GetInterface), "IManagedObject Fail");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
int result = Marshal.QueryInterface(_realInstanceN, ref iid, out ppv);
|
||||
if (result == S_OK)
|
||||
{
|
||||
// Patch the vtable with our own thunks
|
||||
IntPtr origVtbl = Marshal.ReadIntPtr(ppv);
|
||||
|
||||
Type iType = null;
|
||||
foreach (Type i in _realInstance.GetType().GetInterfaces())
|
||||
if (i.GUID == iid)
|
||||
{
|
||||
iType = i;
|
||||
break;
|
||||
}
|
||||
if (iType != null)
|
||||
{
|
||||
// TODO generate proper thunks in machine code
|
||||
int slotCount = Marshal.GetEndComSlot(iType) + 1;
|
||||
int slotsSizeBytes = IntPtr.Size * slotCount;
|
||||
IntPtr newVtbl = Marshal.AllocHGlobal(slotsSizeBytes);
|
||||
...
|
||||
}
|
||||
|
||||
Ext.LogCall(_realInstance.GetType().Name, nameof(GetInterface), (iType == null ? iid.ToString() : iType.Name) + " OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
Ext.LogCall(_realInstance.GetType().Name, nameof(GetInterface), iid.ToString() + " Fail");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int AddRef(IntPtr @this)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private int Release(IntPtr @this)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
VisualStudioMock/Ext.cs
Normal file
31
VisualStudioMock/Ext.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
static class Ext
|
||||
{
|
||||
public static void Log(string message)
|
||||
{
|
||||
Console.WriteLine("Mock: " + message);
|
||||
}
|
||||
|
||||
public static void LogCall(string @class, string method, string message = null)
|
||||
{
|
||||
Console.WriteLine("Mock call: " + @class + "!" + method + " " + message);
|
||||
}
|
||||
|
||||
public static void LogEnter(string @class, string method)
|
||||
{
|
||||
Console.WriteLine("Mock enter: " + @class + "!" + method);
|
||||
}
|
||||
|
||||
public static void LogExit(string @class, string method)
|
||||
{
|
||||
Console.WriteLine("Mock exit: " + @class + "!" + method);
|
||||
}
|
||||
|
||||
public static U ComBarrier<T, U>(this T instance) where T : U {
|
||||
return (U)(new ComProxy(instance).GetIUnknown());
|
||||
}
|
||||
}
|
||||
}
|
||||
41
VisualStudioMock/IEnumSetupInstances.cs
Normal file
41
VisualStudioMock/IEnumSetupInstances.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// An enumerator of installed <see cref="ISetupInstance" /> objects.
|
||||
/// </summary>
|
||||
[ComImport]
|
||||
[ComVisible(true)]
|
||||
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface IEnumSetupInstances
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves the next set of product instances in the enumeration sequence.
|
||||
/// </summary>
|
||||
/// <param name="celt">The number of product instances to retrieve.</param>
|
||||
/// <param name="rgelt">A pointer to an array of <see cref="ISetupInstance" />.</param>
|
||||
/// <param name="pceltFetched">A pointer to the number of product instances retrieved. If <paramref name="celt" /> is 1 this parameter may be NULL.</param>
|
||||
void Next([In] [MarshalAs(UnmanagedType.U4)] int celt, [Out] [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface)] ISetupInstance[] rgelt, [MarshalAs(UnmanagedType.U4)] out int pceltFetched);
|
||||
|
||||
/// <summary>
|
||||
/// Skips the next set of product instances in the enumeration sequence.
|
||||
/// </summary>
|
||||
/// <param name="celt">The number of product instances to skip.</param>
|
||||
void Skip([In] [MarshalAs(UnmanagedType.U4)] int celt);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the enumeration sequence to the beginning.
|
||||
/// </summary>
|
||||
void Reset();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new enumeration object in the same state as the current enumeration object: the new object points to the same place in the enumeration sequence.
|
||||
/// </summary>
|
||||
/// <returns>A pointer to a pointer to a new <see cref="T:Microsoft.VisualStudio.Setup.Configuration.IEnumSetupInstances" /> interface. If the method fails, this parameter is undefined.</returns>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances Clone();
|
||||
}
|
||||
}
|
||||
42
VisualStudioMock/ISetupConfiguration.cs
Normal file
42
VisualStudioMock/ISetupConfiguration.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets information about product instances installed on the machine.
|
||||
/// </summary>
|
||||
[ComImport]
|
||||
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerates all launchable product instances installed.
|
||||
/// </summary>
|
||||
/// <returns>An enumeration of installed product instances.</returns>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances EnumInstances();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance for the current process path.
|
||||
/// </summary>
|
||||
/// <returns>The instance for the current process path.</returns>
|
||||
/// <remarks>
|
||||
/// The returned instance may not be launchable.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForCurrentProcess();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance for the given path.
|
||||
/// </summary>
|
||||
/// <param name="path">Path used to determine instance</param>
|
||||
/// <returns>The instance for the given path.</returns>
|
||||
/// <remarks>
|
||||
/// The returned instance may not be launchable.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForPath([In] [MarshalAs(UnmanagedType.LPWStr)] string path);
|
||||
}
|
||||
}
|
||||
49
VisualStudioMock/ISetupConfiguration2.cs
Normal file
49
VisualStudioMock/ISetupConfiguration2.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets information about product instances set up on the machine.
|
||||
/// </summary>
|
||||
[ComImport]
|
||||
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupConfiguration2 : ISetupConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerates all launchable product instances installed.
|
||||
/// </summary>
|
||||
/// <returns>An enumeration of installed product instances.</returns>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
new IEnumSetupInstances EnumInstances();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance for the current process path.
|
||||
/// </summary>
|
||||
/// <returns>The instance for the current process path.</returns>
|
||||
/// <remarks>
|
||||
/// The returned instance may not be launchable.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
new ISetupInstance GetInstanceForCurrentProcess();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance for the given path.
|
||||
/// </summary>
|
||||
/// <param name="path">Path used to determine instance</param>
|
||||
/// <returns>The instance for the given path.</returns>
|
||||
/// <remarks>
|
||||
/// The returned instance may not be launchable.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
new ISetupInstance GetInstanceForPath([In] [MarshalAs(UnmanagedType.LPWStr)] string path);
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all product instances.
|
||||
/// </summary>
|
||||
/// <returns>An enumeration of all product instances.</returns>
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances EnumAllInstances();
|
||||
}
|
||||
}
|
||||
30
VisualStudioMock/ISetupErrorState.cs
Normal file
30
VisualStudioMock/ISetupErrorState.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about the error state of an instance.
|
||||
/// </summary>
|
||||
[ComImport]
|
||||
[Guid("46DCCD94-A287-476A-851E-DFBC2FFDBC20")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupErrorState
|
||||
{
|
||||
/*
|
||||
/// <summary>
|
||||
/// Gets an array of failed package references.
|
||||
/// </summary>
|
||||
/// <returns>An array of failed package references.</returns>
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||||
ISetupFailedPackageReference[] GetFailedPackages();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of skipped package references.
|
||||
/// </summary>
|
||||
/// <returns>An array of skipped package references.</returns>
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||||
ISetupPackageReference[] GetSkippedPackages();
|
||||
*/
|
||||
}
|
||||
}
|
||||
77
VisualStudioMock/ISetupInstance.cs
Normal file
77
VisualStudioMock/ISetupInstance.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about an instance of a product.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can enumerate all properties of basic types by casting to an <see cref="ISetupPropertyStore" />.
|
||||
/// </remarks>
|
||||
[ComImport]
|
||||
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the instance identifier (should match the name of the parent instance directory).
|
||||
/// </summary>
|
||||
/// <returns>The instance identifier.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstanceId();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local date and time when the installation was originally installed.
|
||||
/// </summary>
|
||||
/// <returns>The local date and time when the installation was originally installed.</returns>
|
||||
[return: MarshalAs(UnmanagedType.Struct)]
|
||||
FILETIME GetInstallDate();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique name of the installation, often indicating the branch and other information used for telemetry.
|
||||
/// </summary>
|
||||
/// <returns>The unique name of the installation, often indicating the branch and other information used for telemetry.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationName();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the installation root of the product.
|
||||
/// </summary>
|
||||
/// <returns>The path to the installation root of the product.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationPath();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of the product installed in this instance.
|
||||
/// </summary>
|
||||
/// <returns>The version of the product installed in this instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetInstallationVersion();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display name (title) of the product installed in this instance.
|
||||
/// </summary>
|
||||
/// <param name="lcid">The LCID for the display name.</param>
|
||||
/// <returns>The display name (title) of the product installed in this instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetDisplayName([In] [MarshalAs(UnmanagedType.U4)] int lcid = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the product installed in this instance.
|
||||
/// </summary>
|
||||
/// <param name="lcid">The LCID for the description.</param>
|
||||
/// <returns>The description of the product installed in this instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetDescription([In] [MarshalAs(UnmanagedType.U4)] int lcid = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the optional relative path to the root path of the instance.
|
||||
/// </summary>
|
||||
/// <param name="pwszRelativePath">A relative path within the instance to resolve, or NULL to get the root path.</param>
|
||||
/// <returns>The full path to the optional relative path within the instance. If the relative path is NULL, the root path will always terminate in a backslash.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string ResolvePath([In] [MarshalAs(UnmanagedType.LPWStr)] string pwszRelativePath = null);
|
||||
}
|
||||
}
|
||||
83
VisualStudioMock/ISetupInstance2.cs
Normal file
83
VisualStudioMock/ISetupInstance2.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Information about an instance of a product.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can enumerate all properties of basic types by casting to an <see cref="ISetupPropertyStore" />.
|
||||
/// </remarks>
|
||||
[ComImport]
|
||||
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupInstance2 : ISetupInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the state of the instance.
|
||||
/// </summary>
|
||||
/// <returns>The state of the instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
InstanceState GetState();
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of package references registered to the instance.
|
||||
/// </summary>
|
||||
/// <returns>An array of package references registered to the instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
||||
ISetupPackageReference[] GetPackages();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a package reference to the product registered to the instance
|
||||
/// </summary>
|
||||
/// <returns>A package reference to the product registered to the instance. This may be null if <see cref="M:Microsoft.VisualStudio.Setup.Configuration.ISetupInstance2.GetState" /> does not return <see cref="F:Microsoft.VisualStudio.Setup.Configuration.InstanceState.Complete" />.</returns>
|
||||
ISetupPackageReference GetProduct();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the relative path to the product application, if available.
|
||||
/// </summary>
|
||||
/// <returns>The relative path to the product application, if available.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetProductPath();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error state of the instance, if available.
|
||||
/// </summary>
|
||||
/// <returns>The error state of the instance, if available.</returns>
|
||||
ISetupErrorState GetErrors();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the instance can be launched.
|
||||
/// </summary>
|
||||
/// <returns>Whether the instance can be launched.</returns>
|
||||
/// <remarks>
|
||||
/// An instance could have had errors during install but still be launched. Some features may not work correctly, but others will.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool IsLaunchable();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the instance is complete.
|
||||
/// </summary>
|
||||
/// <returns>Whether the instance is complete.</returns>
|
||||
/// <remarks>
|
||||
/// An instance is complete if it had no errors during install, resume, or repair.
|
||||
/// </remarks>
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool IsComplete();
|
||||
|
||||
/// <summary>
|
||||
/// Gets product-specific properties.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="T:Microsoft.VisualStudio.Setup.Configuration.ISetupPropertyStore" /> of product-specific properties, or null if no properties are defined.</returns>
|
||||
ISetupPropertyStore GetProperties();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory path to the setup engine that installed the instance.
|
||||
/// </summary>
|
||||
/// <returns>The directory path to the setup engine that installed the instance.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetEnginePath();
|
||||
}
|
||||
}
|
||||
73
VisualStudioMock/ISetupPackageReference.cs
Normal file
73
VisualStudioMock/ISetupPackageReference.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// A reference to a package.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can enumerate all properties of basic types by casting to an <see cref="ISetupPropertyStore" />.
|
||||
/// </remarks>
|
||||
[ComImport]
|
||||
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupPackageReference
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the general package identifier.
|
||||
/// </summary>
|
||||
/// <returns>The general package identifier.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetId();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of the package.
|
||||
/// </summary>
|
||||
/// <returns>The version of the package.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetVersion();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target process architecture of the package.
|
||||
/// </summary>
|
||||
/// <returns>The target process architecture of the package.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetChip();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the language and optional region identifier.
|
||||
/// </summary>
|
||||
/// <returns>The language and optional region identifier.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetLanguage();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the build branch of the package.
|
||||
/// </summary>
|
||||
/// <returns>The build branch of the package.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetBranch();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the package.
|
||||
/// </summary>
|
||||
/// <returns>The type of the package.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
new string GetType();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier consisting of all defined tokens.
|
||||
/// </summary>
|
||||
/// <returns>The unique identifier consisting of all defined tokens.</returns>
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
string GetUniqueId();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the package refers to an external extension.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether the package refers to an external extension.</returns>
|
||||
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||
bool GetIsExtension();
|
||||
}
|
||||
}
|
||||
31
VisualStudioMock/ISetupPropertyStore.cs
Normal file
31
VisualStudioMock/ISetupPropertyStore.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides named properties.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You can get this from an <see cref="ISetupInstance" />, <see cref="ISetupPackageReference" />, or derivative.
|
||||
/// </remarks>
|
||||
[ComImport]
|
||||
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupPropertyStore
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an array of property names in this property store.
|
||||
/// </summary>
|
||||
/// <returns>An array of property names in this property store.</returns>
|
||||
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
|
||||
string[] GetNames();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a named property in this property store.
|
||||
/// </summary>
|
||||
/// <param name="pwszName">The name of the property to get.</param>
|
||||
/// <returns>The value of the property.</returns>
|
||||
object GetValue([In] [MarshalAs(UnmanagedType.LPWStr)] string pwszName);
|
||||
}
|
||||
}
|
||||
36
VisualStudioMock/InstanceState.cs
Normal file
36
VisualStudioMock/InstanceState.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of an <see cref="ISetupInstance2" />.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum InstanceState : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance state has not been determined.
|
||||
/// </summary>
|
||||
None = 0x0,
|
||||
/// <summary>
|
||||
/// The instance installation path exists.
|
||||
/// </summary>
|
||||
Local = 0x1,
|
||||
/// <summary>
|
||||
/// A product is registered to the instance.
|
||||
/// </summary>
|
||||
Registered = 0x2,
|
||||
/// <summary>
|
||||
/// No reboot is required for the instance.
|
||||
/// </summary>
|
||||
NoRebootRequired = 0x4,
|
||||
/// <summary>
|
||||
/// No errors were reported for the instance.
|
||||
/// </summary>
|
||||
NoErrors = 0x8,
|
||||
/// <summary>
|
||||
/// The instance represents a complete install.
|
||||
/// </summary>
|
||||
Complete = uint.MaxValue
|
||||
}
|
||||
}
|
||||
50
VisualStudioMock/Program.cs
Normal file
50
VisualStudioMock/Program.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.Win32;
|
||||
|
||||
[assembly: AssemblyCompany("Ivasoft s.r.o.")]
|
||||
[assembly: AssemblyProduct("VisualStudioMock")]
|
||||
[assembly: AssemblyTitle("Visual Studio Mock for EAZfuscator")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => Console.WriteLine("Exception: " + e.ExceptionObject);
|
||||
|
||||
if (args.Length == 1)
|
||||
switch (args[0]) {
|
||||
case "/reg":
|
||||
using (RegistryKey regBase = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64))
|
||||
using (RegistryKey regCoClass = regBase.CreateSubKey("CLSID\\{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}\\InprocServer32"))
|
||||
{
|
||||
regCoClass.SetValue("", "mscoree.dll");
|
||||
regCoClass.SetValue("Class", "VisualStudioMock.SetupConfiguration");
|
||||
regCoClass.SetValue("Assembly", "VisualStudioMock, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
|
||||
regCoClass.SetValue("RuntimeVersion", "v4.0.30319");
|
||||
regCoClass.SetValue("ThreadingModel", "Apartment");
|
||||
regCoClass.SetValue("CodeBase", Assembly.GetExecutingAssembly().Location);
|
||||
}
|
||||
Console.WriteLine("Visual Studio Mock registered.");
|
||||
return;
|
||||
|
||||
case "/unreg":
|
||||
using (RegistryKey regBase = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64))
|
||||
{
|
||||
regBase.DeleteSubKey("CLSID\\{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}\\InprocServer32", throwOnMissingSubKey: false);
|
||||
regBase.DeleteSubKey("CLSID\\{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}\\LocalServer32", throwOnMissingSubKey: false);
|
||||
regBase.DeleteSubKey("CLSID\\{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}", throwOnMissingSubKey: false);
|
||||
}
|
||||
Console.WriteLine("Visual Studio Mock unregistered.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Usage: VisualStudioMock.exe [ /reg | /unreg ]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
140
VisualStudioMock/SetupConfiguration.cs
Normal file
140
VisualStudioMock/SetupConfiguration.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
public sealed class SetupConfiguration : ISetupConfiguration, ISetupConfiguration2
|
||||
{
|
||||
private readonly SetupInstance _singleInstance;
|
||||
|
||||
public SetupConfiguration()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupConfiguration), ".ctor");
|
||||
|
||||
ComProxy proxy = new ComProxy(new SetupConfiguration(false));
|
||||
object proxyCcw = proxy.GetIUnknown();
|
||||
|
||||
// Copy managed object
|
||||
GCHandle hThis = GCHandle.Alloc(this, GCHandleType.WeakTrackResurrection);
|
||||
IntPtr pThis = Marshal.ReadIntPtr(GCHandle.ToIntPtr(hThis));
|
||||
GCHandle hProxy = GCHandle.Alloc(proxyCcw, GCHandleType.WeakTrackResurrection);
|
||||
IntPtr pProxy = Marshal.ReadIntPtr(GCHandle.ToIntPtr(hProxy));
|
||||
byte[] buffer = new byte[IntPtr.Size * 3];
|
||||
Marshal.Copy(pProxy - IntPtr.Size, buffer, 0, buffer.Length);
|
||||
Marshal.Copy(buffer, 0, pThis - IntPtr.Size, buffer.Length);
|
||||
|
||||
/*
|
||||
Ext.Log("Casting to ISetupConfiguration");
|
||||
proxyCcw = this;
|
||||
ISetupConfigurationTest wrapper = (ISetupConfigurationTest)proxyCcw;
|
||||
GC.KeepAlive(wrapper.GetInstanceForCurrentProcess());
|
||||
*/
|
||||
|
||||
Ext.LogExit(nameof(SetupConfiguration), ".ctor");
|
||||
}
|
||||
|
||||
private SetupConfiguration(bool any)
|
||||
{
|
||||
this._singleInstance = new SetupInstance();
|
||||
}
|
||||
|
||||
#region ISetupConfiguration Members
|
||||
|
||||
public IEnumSetupInstances EnumInstances()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupConfiguration), nameof(EnumInstances));
|
||||
return new Enum(this).ComBarrier<Enum, IEnumSetupInstances>();
|
||||
}
|
||||
|
||||
public ISetupInstance GetInstanceForCurrentProcess()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupConfiguration), nameof(GetInstanceForCurrentProcess));
|
||||
return _singleInstance.ComBarrier<SetupInstance, ISetupInstance>();
|
||||
}
|
||||
|
||||
public ISetupInstance GetInstanceForPath([In, MarshalAs(UnmanagedType.LPWStr)] string path)
|
||||
{
|
||||
Ext.LogCall(nameof(SetupConfiguration), nameof(GetInstanceForPath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISetupConfiguration2 Members
|
||||
|
||||
public IEnumSetupInstances EnumAllInstances()
|
||||
{
|
||||
Ext.LogEnter(nameof(SetupConfiguration), nameof(EnumAllInstances));
|
||||
IEnumSetupInstances result = new Enum(this).ComBarrier<Enum, IEnumSetupInstances>();
|
||||
Ext.LogExit(nameof(SetupConfiguration), nameof(EnumAllInstances));
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
sealed class Enum : IEnumSetupInstances
|
||||
{
|
||||
private readonly SetupConfiguration _owner;
|
||||
private int _idx;
|
||||
|
||||
internal Enum(SetupConfiguration owner)
|
||||
{
|
||||
this._owner = owner;
|
||||
}
|
||||
|
||||
public IEnumSetupInstances Clone()
|
||||
{
|
||||
Ext.LogCall(nameof(Enum), nameof(Clone));
|
||||
return ((Enum)MemberwiseClone()).ComBarrier<Enum, IEnumSetupInstances>();
|
||||
}
|
||||
|
||||
public void Next([In, MarshalAs(UnmanagedType.U4)] int celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt, [MarshalAs(UnmanagedType.U4)] out int pceltFetched)
|
||||
{
|
||||
Ext.LogEnter(nameof(Enum), nameof(Next));
|
||||
if (_idx == 0 && celt > 0)
|
||||
{
|
||||
rgelt[0] = _owner._singleInstance.ComBarrier<SetupInstance, ISetupInstance>();
|
||||
pceltFetched = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pceltFetched = 0;
|
||||
}
|
||||
Ext.LogExit(nameof(Enum), nameof(Next));
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Ext.LogCall(nameof(Enum), nameof(Reset));
|
||||
_idx = 0;
|
||||
}
|
||||
|
||||
public void Skip([In, MarshalAs(UnmanagedType.U4)] int celt)
|
||||
{
|
||||
Ext.LogEnter(nameof(Enum), nameof(Skip));
|
||||
if (celt < 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
_idx += celt;
|
||||
Ext.LogExit(nameof(Enum), nameof(Skip));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
[ComImport]
|
||||
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
public interface ISetupConfigurationTest
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumSetupInstances EnumInstances();
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForCurrentProcess();
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
ISetupInstance GetInstanceForPath([In] [MarshalAs(UnmanagedType.LPWStr)] string path);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
135
VisualStudioMock/SetupInstance.cs
Normal file
135
VisualStudioMock/SetupInstance.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||||
|
||||
namespace VisualStudioMock
|
||||
{
|
||||
public class SetupInstance : ISetupInstance, ISetupInstance2, ISetupPropertyStore
|
||||
{
|
||||
#region ISetupInstance Members
|
||||
|
||||
public string GetDescription([In, MarshalAs(UnmanagedType.U4)] int lcid = 0)
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetDescription));
|
||||
return "description";
|
||||
}
|
||||
|
||||
public string GetDisplayName([In, MarshalAs(UnmanagedType.U4)] int lcid = 0)
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetDisplayName));
|
||||
return "display name";
|
||||
}
|
||||
|
||||
public string GetInstallationName()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetInstallationName));
|
||||
return "installation name";
|
||||
}
|
||||
|
||||
public string GetInstallationPath()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetInstallationPath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetInstallationVersion()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetInstallationVersion));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public FILETIME GetInstallDate()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetInstallDate));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetInstanceId()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetInstanceId));
|
||||
return "id1";
|
||||
}
|
||||
|
||||
public string ResolvePath([In, MarshalAs(UnmanagedType.LPWStr)] string pwszRelativePath = null)
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(ResolvePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISetupInstance2 Members
|
||||
|
||||
public string GetEnginePath()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetEnginePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ISetupErrorState GetErrors()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetEnginePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ISetupPackageReference[] GetPackages()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetEnginePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ISetupPackageReference GetProduct()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetEnginePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetProductPath()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetEnginePath));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ISetupPropertyStore GetProperties()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetProperties));
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstanceState GetState()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetState));
|
||||
return InstanceState.Complete;
|
||||
}
|
||||
|
||||
public bool IsComplete()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(IsComplete));
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsLaunchable()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(IsLaunchable));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISetupPropertyStore Members
|
||||
|
||||
public string[] GetNames()
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetNames));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object GetValue(string pwszName)
|
||||
{
|
||||
Ext.LogCall(nameof(SetupInstance), nameof(GetValue));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
12
VisualStudioMock/VisualStudioMock.csproj
Normal file
12
VisualStudioMock/VisualStudioMock.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<!--Nullable>enable</Nullable-->
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
23
VisualStudioMockTest/Program.cs
Normal file
23
VisualStudioMockTest/Program.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.VisualStudio.Setup.Configuration;
|
||||
|
||||
class A {
|
||||
public static void Main(string[] args) {
|
||||
Console.WriteLine("Creating instance of SetupConfiguration");
|
||||
SetupConfiguration setup = new SetupConfiguration();
|
||||
Console.WriteLine("Created instance of SetupConfiguration");
|
||||
|
||||
var a = setup.EnumAllInstances();
|
||||
ISetupInstance[] b = new ISetupInstance[1];
|
||||
while (true) {
|
||||
a.Next(1, b, out _);
|
||||
if (b[0] == null)
|
||||
break;
|
||||
|
||||
ISetupInstance c = b[0];
|
||||
Console.WriteLine("Instance - " + c.GetDisplayName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
VisualStudioMockTest/VisualStudioMockTest.csproj
Normal file
10
VisualStudioMockTest/VisualStudioMockTest.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.12.2149" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user