1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolsetTest.Mba.Core
{
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using WixInternal.TestSupport;
using WixToolset.Mba.Core;
using Xunit;
public class BaseBootstrapperApplicationFactoryFixture
{
[Fact]
public void CanCreateBA()
{
var command = new TestCommand
{
action = LaunchAction.Install,
cbSize = Marshal.SizeOf(typeof(TestCommand)),
display = Display.Full,
wzCommandLine = "this \"is a\" test VariableA=AVariable =EmptyName EmptyValue=",
};
var pCommand = Marshal.AllocHGlobal(command.cbSize);
try
{
Marshal.StructureToPtr(command, pCommand, false);
var createArgs = new BootstrapperCreateArgs(0, IntPtr.Zero, IntPtr.Zero, pCommand);
var pArgs = Marshal.AllocHGlobal(createArgs.cbSize);
try
{
Marshal.StructureToPtr(createArgs, pArgs, false);
var createResults = new TestCreateResults
{
cbSize = Marshal.SizeOf<TestCreateResults>(),
};
var pResults = Marshal.AllocHGlobal(createResults.cbSize);
try
{
var baFactory = new TestBAFactory();
baFactory.Create(pArgs, pResults);
createResults = Marshal.PtrToStructure<TestCreateResults>(pResults);
Assert.Equal(baFactory.BA, createResults.pBA);
Assert.Equal(baFactory.BA.Command.Action, command.action);
Assert.Equal(baFactory.BA.Command.Display, command.display);
var mbaCommand = baFactory.BA.Command.ParseCommandLine();
WixAssert.CompareLineByLine(mbaCommand.UnknownCommandLineArgs, new string[] { "this", "is a", "test" });
Assert.Equal(mbaCommand.Variables, new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("VariableA", "AVariable"),
new KeyValuePair<string, string>("", "EmptyName"),
new KeyValuePair<string, string>("EmptyValue", ""),
});
}
finally
{
Marshal.FreeHGlobal(pResults);
}
}
finally
{
Marshal.FreeHGlobal(pArgs);
}
}
finally
{
Marshal.FreeHGlobal(pCommand);
}
}
internal class TestBAFactory : BaseBootstrapperApplicationFactory
{
public TestBA BA { get; private set; }
protected override IBootstrapperApplication Create(IEngine engine, IBootstrapperCommand bootstrapperCommand)
{
this.BA = new TestBA(engine, bootstrapperCommand);
return this.BA;
}
}
internal class TestBA : BootstrapperApplication
{
public IBootstrapperCommand Command { get; }
public TestBA(IEngine engine, IBootstrapperCommand command)
: base(engine)
{
this.Command = command;
}
protected override void Run()
{
}
}
[StructLayout(LayoutKind.Sequential)]
public struct TestCommand
{
public int cbSize;
public LaunchAction action;
public Display display;
[MarshalAs(UnmanagedType.LPWStr)] public string wzCommandLine;
public int nCmdShow;
public ResumeType resume;
public IntPtr hwndSplashScreen;
public RelationType relation;
[MarshalAs(UnmanagedType.Bool)] public bool passthrough;
[MarshalAs(UnmanagedType.LPWStr)] public string wzLayoutDirectory;
}
[StructLayout(LayoutKind.Sequential)]
public struct BootstrapperCreateArgs
{
[MarshalAs(UnmanagedType.I4)] public readonly int cbSize;
[MarshalAs(UnmanagedType.I8)] public readonly long qwEngineAPIVersion;
public readonly IntPtr pfnBootstrapperEngineProc;
public readonly IntPtr pvBootstrapperEngineProcContext;
public readonly IntPtr pCommand;
public BootstrapperCreateArgs(long version, IntPtr pEngineProc, IntPtr pEngineContext, IntPtr pCommand)
{
this.cbSize = Marshal.SizeOf(typeof(BootstrapperCreateArgs));
this.qwEngineAPIVersion = version;
this.pfnBootstrapperEngineProc = pEngineProc;
this.pvBootstrapperEngineProcContext = pEngineContext;
this.pCommand = pCommand;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct TestCreateResults
{
public int cbSize;
public IntPtr pBAProc;
[MarshalAs(UnmanagedType.Interface)] public IBootstrapperApplication pBA;
}
}
}
|