forked from CosmosOS/Cosmos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVMware.cs
196 lines (177 loc) · 7.3 KB
/
VMware.cs
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Microsoft.Win32;
//using Vestris.VMWareLib;
using Cosmos.Build.Common;
namespace Cosmos.Debug.Hosts {
public class VMware : Host {
protected VMwareEdition mEdition;
protected string mDir;
protected string mVmxPath;
protected Process mProcess;
protected string mWorkstationPath;
protected string mPlayerPath;
protected string mHarddisk;
public VMware(Dictionary<string, string> aParams, bool aUseGDB,string harddisk = "Filesystem.vmdk") : base(aParams, aUseGDB) {
mHarddisk = harddisk;
mDir = Path.Combine(CosmosPaths.Build, @"VMWare\Workstation\");
mVmxPath = Path.Combine(mDir, @"Debug.vmx");
mWorkstationPath = GetPathname("VMware Workstation", "vmware.exe");
mPlayerPath = GetPathname("VMware Player", "vmplayer.exe");
if (mWorkstationPath == null && mPlayerPath == null) {
throw new Exception("VMware not found.");
}
string xFlavor = aParams[BuildPropertyNames.VMwareEditionString].ToUpper();
mEdition = VMwareEdition.Player;
if (xFlavor == "WORKSTATION") {
mEdition = VMwareEdition.Workstation;
}
// Try alternate if selected one is not installed
if (mEdition == VMwareEdition.Player && mPlayerPath == null && mWorkstationPath != null) {
mEdition = VMwareEdition.Workstation;
} else if (mEdition == VMwareEdition.Workstation && mWorkstationPath == null) {
mEdition = VMwareEdition.Player;
}
}
//protected void ConnectToVMWare(VMWareVirtualHost aHost) {
// if (mEdition != VMwareEdition.Player) {
// aHost.ConnectToVMWareWorkstation();
// } else {
// aHost.ConnectToVMWarePlayer();
// }
//}
protected string GetPathname(string aKey, string aEXE) {
using (var xRegKey = Registry.LocalMachine.OpenSubKey(@"Software\VMware, Inc.\" + aKey, false)) {
if (xRegKey != null) {
string xResult = Path.Combine(((string)xRegKey.GetValue("InstallPath")), aEXE);
if (File.Exists(xResult)) {
return xResult;
}
}
return null;
}
}
public override void Start() {
Cleanup();
CreateDebugVmx();
// Target exe or file
mProcess = new Process();
var xPSI = mProcess.StartInfo;
if (mEdition == VMwareEdition.Player) {
xPSI.FileName = mPlayerPath;
} else {
xPSI.FileName = mWorkstationPath;
}
var xArgSB = new StringBuilder();
string xVmxPath = "\"" + mVmxPath + "\"";
if (mEdition == VMwareEdition.Player) {
xPSI.Arguments = xVmxPath;
} else {
// -x: Auto power on VM. Must be small x, big X means something else.
// -q: Close VMWare when VM is powered off.
// Options must come beore the vmx, and cannot use shellexecute
xPSI.Arguments = "-x -q " + xVmxPath;
}
xPSI.UseShellExecute = false; //must be true to allow elevate the process, sometimes needed if vmware only runs with admin rights
mProcess.EnableRaisingEvents = true;
mProcess.Exited += delegate(Object aSender, EventArgs e) {
if (OnShutDown != null) {
OnShutDown(aSender, e);
}
};
mProcess.Start();
}
public override void Stop() {
//using (var xHost = new VMWareVirtualHost()) {
// ConnectToVMWare(xHost);
// using (var xMachine = xHost.Open(mVmxPath)) {
// xMachine.PowerOff();
// }
// xHost.Close();
//}
Cleanup();
}
protected void DeleteFiles(string aPath, string aPattern) {
var xFiles = Directory.GetFiles(aPath, aPattern);
foreach (var xFile in xFiles) {
File.Delete(xFile);
}
}
protected void Cleanup() {
try {
string xPath = Path.GetDirectoryName(mVmxPath);
// Delete old Debug.vmx and other files that might be left over from previous run.
// Especially important with newer versions of VMWare player which defaults to suspend
// when the close button is used.
File.Delete(mVmxPath);
File.Delete(Path.ChangeExtension(mVmxPath, ".nvram"));
// Delete the auto snapshots that latest vmware players create as default.
// It creates them with suffixes though, so we need to wild card find them.
DeleteFiles(xPath, "*.vmxf");
DeleteFiles(xPath, "*.vmss");
DeleteFiles(xPath, "*.vmsd");
DeleteFiles(xPath, "*.vmem");
// Delete log files so that logged data is only from last boot
File.Delete(Path.Combine(xPath, "vmware.log"));
File.Delete(Path.Combine(xPath, "vmware-0.log"));
File.Delete(Path.Combine(xPath, "vmware-1.log"));
File.Delete(Path.Combine(xPath, "vmware-2.log"));
} catch (Exception) {
// Ignore errors, users can stop VS while VMware is still running and files will be locked.
}
}
protected void CreateDebugVmx() {
// VMWare doesn't like to boot a read only VMX.
// We also need to make changes based on project / debug settings.
// Finally we do not want to create VCS checkins based on local user changes.
// Because of this we use Cosmos.vmx as a template and output a Debug.vmx on every run.
using (var xSrc = new StreamReader(File.Open(Path.Combine(mDir, "Cosmos.vmx"), FileMode.OpenOrCreate))) {
try {
// Write out Debug.vmx
using (var xDest = new StreamWriter(File.Open(mVmxPath, FileMode.Create))) {
string xLine;
while ((xLine = xSrc.ReadLine()) != null) {
var xParts = xLine.Split('=');
if (xParts.Length == 2) {
string xName = xParts[0].Trim();
string xValue = xParts[1].Trim();
if ((xName == "uuid.location") || (xName == "uuid.bios")) {
// We delete uuid entries so VMWare doesnt ask the user "Did you move or copy" the file
xValue = null;
} else if (xName == "ide1:0.fileName")
{
// Set the ISO file for booting
xValue = "\"" + mParams["ISOFile"] + "\"";
} else if (xName == "ide0:0.fileName") {
xValue = "\"" + mHarddisk + "\"";
} else if (xName == "nvram") {
// Point it to an initially non-existent nvram.
// This has the effect of disabling PXE so the boot is faster.
xValue = "\"Debug.nvram\"";
}
if (xValue != null) {
xDest.WriteLine(xName + " = " + xValue);
}
}
}
if (mUseGDB) {
xDest.WriteLine();
xDest.WriteLine("debugStub.listen.guest32 = \"TRUE\"");
xDest.WriteLine("debugStub.hideBreakpoints = \"TRUE\"");
xDest.WriteLine("monitor.debugOnStartGuest32 = \"TRUE\"");
xDest.WriteLine("debugStub.listen.guest32.remote = \"TRUE\"");
}
}
} catch (IOException ex) {
if (ex.Message.Contains(Path.GetFileName(mDir))) {
throw new Exception("The VMware image " + mDir + " is still in use. Please exit current Vmware session with Cosmos and try again.", ex);
}
throw;
}
}
}
}
}