public void LoadPluginIntoProcess()
{
IntPtr hModule;
//Serialize configuration XML.
var eradstyle = XmlSerializationHelper.Deserialize<config>("launcher.xml");
//Get handle for the selected ffxiv process.
var hProc = _mapper.OpenHan(0x001F0FFF, _pid);
//Check if the CLR is already loaded into the selected process.
if (Process.GetProcessById(_pid).Modules.Cast<ProcessModule>().Any(mod => mod.ModuleName == "clr.dll"))
{
hModule = eradstyle.MemInfo.First(id => id.ID == _pid).hModule;
}
//CLR not loaded. Map new instance of the CLR, into the ffxiv process.
else
{
hModule = _mapper.Inject(Properties.Resources.Link, hProc);
if (hModule == IntPtr.Zero)
{
MessageBox.Show("Something blocked Bolter from loading, Check any Virus Scanners, or Windows Restrictions");
StartButton.IsEnabled = true;
return;
}
}
var mainNamespace = MainNamespaceOfPlugin(SelectedpluginName);
var pInfo = new PassInfo
{
DomainName = mainNamespace,
FilePath = string.Format("{0}\\Plugins\\{1}.dll", Directory.GetCurrentDirectory(), SelectedpluginName),
};
var ppInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PassInfo)));
Marshal.StructureToPtr(pInfo, ppInfo, true);
// Allocate memory in ffxiv to hold the parameters struct.
var pathPtr = _mapper.AllocMem(hProc, (uint)Marshal.SizeOf(typeof(PassInfo)), 0x1000 | 0x2000, 0x04);
SigScan.WriteProcessMemory(hProc, pathPtr, ppInfo, (uint)Marshal.SizeOf(typeof(PassInfo)), new UIntPtr());
Marshal.FreeHGlobal(ppInfo);
// Get pointer for the Load Assembly function, inside our unmanaged CLR host DLL.
var routinePtr = _mapper.GetFuncPointer(hProc, hModule, "LoadIt");
// Remove old pids
eradstyle.MemInfo.RemoveAll(
pe => !Process.GetProcessesByName("ffxiv").Select(p => p.Id).Contains(pe.ID) || pe.ID == _pid);
// Add current pid.
eradstyle.MemInfo.Add(new PastProcess { ID = _pid, hModule = hModule });
// Save configuration.
XmlSerializationHelper.Serialize("launcher.xml", eradstyle);
// Create remote thread in the selected ffxiv process starting at the Load Assembly routine.
var ntThread = _mapper.CreateThread(hProc, routinePtr, pathPtr);
// Wait for completion or 2000ms.
Dispatcher.BeginInvoke(new Action(delegate
{
DebugButton.Visibility = Visibility.Hidden;
LoadingText.Visibility = Visibility.Visible;
}));
eHandle.WaitOne();
Dispatcher.BeginInvoke(new Action(delegate
{
DebugButton.Visibility = Visibility.Visible;
LoadingText.Visibility = Visibility.Hidden;
}));
// Close handles.
_mapper.CloseHan(ntThread);
_mapper.CloseHan(hProc);
}