623 lines
20 KiB
C#
623 lines
20 KiB
C#
/* ===================
|
||
* WM_COPYDATA example
|
||
* ===================
|
||
*
|
||
* Working example for sending a string between C# handles (Controls/Forms) using WM_COPYDATA.
|
||
*
|
||
* TODO:
|
||
* -----
|
||
* * Add more info
|
||
* * Make generic struct copying work
|
||
*
|
||
*
|
||
* TL;DR:
|
||
* ------
|
||
* Put Catcher.Demo() in Program.Main() and step through it.
|
||
* `MessagePasser.SendString(<handle>, "test");` will send a string to the Handle.
|
||
* Make sure target window WndProc has `MessagePasser.ReceiveString` in it/
|
||
*
|
||
*/
|
||
using Microsoft.InformationProtection;
|
||
using System;
|
||
using System.ComponentModel;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Runtime.InteropServices;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using static BSOneMip.Action;
|
||
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using System.Xml.Linq;
|
||
using Microsoft.Win32;
|
||
using System.Reflection.Emit;
|
||
using System.Linq.Expressions;
|
||
using System.IO;
|
||
//using static BSOneMip.Define;
|
||
|
||
namespace PassMessage {
|
||
|
||
/// <summary>
|
||
/// A form to demonstrate WndProc CopyData
|
||
/// </summary>
|
||
|
||
|
||
public class BS1Aip : Form {
|
||
|
||
private static BS1Aip mInstance;
|
||
public delegate void CopyStringDelegate(string msg);
|
||
public delegate void CopyDataDelegate(CopyData msg);
|
||
public static event CopyStringDelegate StringCopied;
|
||
public static event CopyDataDelegate DataCopied;
|
||
//public static BSOneMip.Action ac_;
|
||
public static int nProcResult_ = 99;
|
||
private static TaskCompletionSource<BS1Aip> onLoad = new TaskCompletionSource<BS1Aip>();
|
||
public static IntPtr hMod_;
|
||
|
||
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
|
||
private extern static IntPtr LoadLibrary(string librayName);
|
||
|
||
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi)]
|
||
private extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);
|
||
|
||
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
|
||
private extern static bool FreeLibrary(IntPtr hModule);
|
||
|
||
[DllImport("kernel32")]
|
||
public static extern Int32 GetLastError();
|
||
|
||
[DllImport("user32.dll", SetLastError = true)]
|
||
public static extern bool ChangeWindowMessageFilter(uint message, uint dwFlag);
|
||
|
||
//private const uint WM_DROPFILES = 0x233;
|
||
private const uint WM_COPYDATA = 0x004A;
|
||
//private const uint WM_COPYGLOBALDATA = 0x0049;
|
||
private const uint MSGFLT_ADD = 1;
|
||
|
||
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||
public delegate int FP_DSCSIsEncryptedFile(string sPath);
|
||
|
||
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||
public delegate int FP_DSCSDecryptFile(string sSrcPath, string sDestPath);
|
||
|
||
public static FP_DSCSIsEncryptedFile DSCSIsEncryptedFile;
|
||
public static FP_DSCSDecryptFile DSCSDecryptFile;
|
||
|
||
public BS1Aip() {
|
||
this.ShowInTaskbar = false; // <20>۾<EFBFBD>ǥ<EFBFBD><C7A5><EFBFBD>ٿ<EFBFBD><D9BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
this.Opacity = 0; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0
|
||
|
||
this.Width = 1;
|
||
this.Height = 1;
|
||
this.Text = "BSOne-AIP-T140713-" + System.IO.Path.GetFileName(Application.ExecutablePath);
|
||
|
||
DSCSIsEncryptedFile = null;
|
||
DSCSDecryptFile = null;
|
||
hMod_ = LoadLibrary("C:\\Windows\\DSCSLink64.dll");
|
||
if (hMod_ != IntPtr.Zero)
|
||
{
|
||
IntPtr pFuncAddr = IntPtr.Zero;
|
||
pFuncAddr = GetProcAddress(hMod_, "DSCSIsEncryptedFile");
|
||
if (pFuncAddr != IntPtr.Zero)
|
||
DSCSIsEncryptedFile = (FP_DSCSIsEncryptedFile)Marshal.GetDelegateForFunctionPointer(
|
||
pFuncAddr, typeof(FP_DSCSIsEncryptedFile));
|
||
else
|
||
Console.WriteLine(string.Format("GetProcAddress <20><><EFBFBD><EFBFBD> .. Error = {0}", GetLastError()));
|
||
|
||
pFuncAddr = GetProcAddress(hMod_, "DSCSDecryptFile");
|
||
if (pFuncAddr != IntPtr.Zero)
|
||
DSCSDecryptFile = (FP_DSCSDecryptFile)Marshal.GetDelegateForFunctionPointer(
|
||
pFuncAddr, typeof(FP_DSCSDecryptFile));
|
||
}
|
||
|
||
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
|
||
}
|
||
|
||
protected override CreateParams CreateParams
|
||
{
|
||
get
|
||
{
|
||
CreateParams cp = base.CreateParams;
|
||
cp.ExStyle |= 0x80; // alt + tab ȭ<>鿡<EFBFBD><E9BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 23_1204 kku
|
||
//cp.ClassName = "BS1Aip";
|
||
//cp.Style |= 0x00000040; // BS_ICON value
|
||
|
||
return cp;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Creates a catcher window to demonstrate Message Passing
|
||
/// </summary>
|
||
public static void Demo() {
|
||
Start().Wait();
|
||
|
||
StringCopied += Console.WriteLine;
|
||
DataCopied += msg => {
|
||
//Console.WriteLine("Received " + msg.dwData + ": " + msg.lpData);
|
||
};
|
||
|
||
MessagePasser.SendString(GetHandle(), "test");
|
||
MessagePasser.SendString(GetHandle(), 3, "other test");
|
||
|
||
while (IsOpen()) {
|
||
Thread.Sleep(1);
|
||
}
|
||
}
|
||
|
||
class AipEnt
|
||
{
|
||
public string src = "";
|
||
public string dst = "";
|
||
public string lid = "";
|
||
public string ssid = "";
|
||
public string regval = "";
|
||
public string mail = "";
|
||
}
|
||
|
||
public static void RcvCmd(BSOneMip.Action ac, BSOneMip.Action acNoD) // acNoD <20>߰<EFBFBD>, <20><><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF>ؼ<EFBFBD>.. <20><><EFBFBD><EFBFBD>, <20>غ<EFBFBD><D8BA><EFBFBD> <20><>ȣȭ Ȯ<><C8AE>24_0723 kku
|
||
//public static void RcvCmd(BSOneMip.Action ac)
|
||
{
|
||
Start().Wait();
|
||
|
||
//StringCopied += Console.WriteLine;
|
||
DataCopied =
|
||
msg => {
|
||
try
|
||
{
|
||
AipEnt aEnt = JsonConvert.DeserializeObject<AipEnt>(msg.lpData.ToString());
|
||
|
||
BSOneMip.Action.FileOptions options = new BSOneMip.Action.FileOptions
|
||
{
|
||
FileName = aEnt.src,
|
||
OutputName = aEnt.dst,
|
||
ActionSource = ActionSource.Manual,
|
||
AssignmentMethod = AssignmentMethod.Privileged,
|
||
DataState = DataState.Rest,
|
||
GenerateChangeAuditEvent = true,
|
||
IsAuditDiscoveryEnabled = true,
|
||
LabelId = aEnt.lid
|
||
};
|
||
|
||
nProcResult_ = 1;
|
||
int cmd = msg.dwData.ToInt32();
|
||
switch (cmd) // 0 : <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>, 1 : <20><>ȣȭ, 2 : <20><>ȣȭ, 3 : <20><>ȣȭ Ȯ<><C8AE>, 4 : <20><><EFBFBD>̺<EFBFBD> Ȯ<><C8AE>, 5 : <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>, 6 : <20><>ķ <20><>ȣȭ
|
||
{
|
||
case 0: // <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (ac.SaveLabelList(aEnt.src))
|
||
nProcResult_ = 10;
|
||
break;
|
||
case 1: // <20><>ȣȭ
|
||
if (ac.SetProtection(options))
|
||
nProcResult_ = 10;
|
||
break;
|
||
case 2: // <20><>ȣȭ
|
||
if (ac.RemoveProtection(options))
|
||
nProcResult_ = 10;
|
||
break;
|
||
case 3: // <20><>ȣȭ Ȯ<><C8AE>
|
||
if (acNoD.IsProtection(aEnt.src))
|
||
nProcResult_ = 10;
|
||
break;
|
||
case 4: // <20><><EFBFBD>̺<EFBFBD> Ȯ<><C8AE>
|
||
var ALabel = ac.GetLabel(options);
|
||
var sLabelName = "";
|
||
if (ALabel != null)
|
||
sLabelName = ALabel.Label.Name;
|
||
|
||
RegistryKey reg;
|
||
if (aEnt.ssid != "")
|
||
reg = Registry.Users.CreateSubKey(aEnt.ssid + "\\SOFTWARE").CreateSubKey("eCrmHomeEdition");
|
||
else
|
||
reg = Registry.LocalMachine.CreateSubKey("SOFTWARE").CreateSubKey("eCrmHomeEdition");
|
||
|
||
//if (reg != null)
|
||
//{
|
||
var sRegVal = aEnt.regval;
|
||
if (sRegVal == "")
|
||
sRegVal = "ALabel";
|
||
|
||
reg.SetValue(sRegVal, sLabelName, RegistryValueKind.String);
|
||
nProcResult_ = 10;
|
||
//}
|
||
|
||
break;
|
||
case 5: // <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> kku, 23_1113
|
||
string sEmpNo = ac.GetEmpNo();
|
||
string sPxMail = aEnt.mail; // proxyAddress ó<><C3B3> <20>߰<EFBFBD> 23_1228 kku
|
||
string sFOwner = ac.GetOwner(aEnt.src);
|
||
|
||
int i = sFOwner.IndexOf('@');
|
||
if (i > 0)
|
||
sFOwner = sFOwner.Substring(0, i);
|
||
|
||
i = sPxMail.IndexOf('@');
|
||
if (i > 0)
|
||
sPxMail = sPxMail.Substring(0, i);
|
||
|
||
nProcResult_ = 2;
|
||
if ((sFOwner == "") || (sEmpNo == sFOwner) || (sPxMail == sFOwner))
|
||
{
|
||
nProcResult_ = 3;
|
||
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٸ<EFBFBD><D9B8><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> kku, 23_1110
|
||
//options.LabelId = "";
|
||
ContentLabel ALabel2 = null;
|
||
try
|
||
{
|
||
ALabel2 = ac.GetLabel(options);
|
||
}
|
||
catch {
|
||
ALabel2 = null;
|
||
}
|
||
|
||
#if _HDENG_
|
||
if ((ALabel2 != null) && (ALabel2.Label != null))
|
||
{
|
||
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> "<22><><EFBFBD><EFBFBD>(Secret)"<22≯<EFBFBD> <20><><EFBFBD><EFBFBD> 24_0527 kku
|
||
if (ALabel2.Label.Id == "1bd401ce-2296-409e-b28d-ebe7aa124c57")
|
||
{
|
||
nProcResult_ = 22;
|
||
return;
|
||
}
|
||
|
||
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> "<22>غ<EFBFBD>(Top-Secret)"<22><> <20><><EFBFBD><EFBFBD> 24_0527 kku
|
||
if (ALabel2.Label.Id == "ba70c971-4f13-4229-83fa-9d8a22a0788e")
|
||
{
|
||
nProcResult_ = 33;
|
||
return;
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
nProcResult_ = 4;
|
||
if ((ALabel2 == null) || (ALabel2.Label == null) ||
|
||
(ALabel2.Label.Id == "") || (ALabel2.Label.Id != aEnt.lid))
|
||
{
|
||
#if _KDNVN_
|
||
if ((ALabel2 != null) && (ALabel2.Label != null))
|
||
{
|
||
if (ALabel2.Label.Id == "5b6a34f5-525c-4c52-b832-c9c630e05005") // <20>Ϲ<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Public Release)
|
||
{
|
||
options.LabelId = "7c1e97b0-1625-488a-a30c-4f2188693461"; // <20>Ϲ<EFBFBD> (General Purpose)
|
||
}
|
||
else if (ALabel2.Label.Id == "f2fa99e1-c17d-4934-9665-44d4df5ef1e6") // <20><><EFBFBD>ܺ<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Confidential Release)
|
||
{
|
||
options.LabelId = "e7bd3a2c-b905-4bdb-8892-e6cd8d1eb00b"; // <20><><EFBFBD>ܺ<EFBFBD> (Confidential)
|
||
}
|
||
else if (ALabel2.Label.Id == "3fce3511-ace7-47a2-8106-f8bf1be7332b") // <20><><EFBFBD><EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Secret Release)
|
||
{
|
||
options.LabelId = "7d1539f9-8f3b-4cbd-b787-7ae1b30eae22"; // <20><><EFBFBD><EFBFBD> (Secret)
|
||
}
|
||
else if (ALabel2.Label.Id == "9f09d5d6-3008-4f6d-b4d3-c978a7d30f16") // <20>غ<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Top Secret Release)
|
||
{
|
||
options.LabelId = "b40a7c1a-5443-458b-9215-2abda0acc4a4"; // <20>غ<EFBFBD> (Top Secret)
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
#if _UNITUS_
|
||
if ((ALabel2 != null) && (ALabel2.Label != null))
|
||
{
|
||
if ( (ALabel2.Label.Id == "da2900a7-a8d4-4880-8110-5ead362bd600") ||
|
||
(ALabel2.Label.Id == "26783f26-fa77-46b6-95df-19ceac22456f") ||
|
||
(ALabel2.Label.Id == "4db57f7c-4e09-49fc-a866-84a60c363440") ||
|
||
(ALabel2.Label.Id == "555d3b5c-162b-43bf-a400-f553314e6743") ) // Top Secret <20><><EFBFBD>̺<EFBFBD><CCBA≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 24_1211 kku
|
||
{
|
||
nProcResult_ = 20;
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
#if _MOTRAS_
|
||
if ((ALabel2 != null) && (ALabel2.Label != null))
|
||
{
|
||
if ( (ALabel2.Label.Id == "0ab0807a-d010-48fe-84fa-5c445d40d3e3") ||
|
||
(ALabel2.Label.Id == "70c3db47-908f-4fcb-bac6-e31e97fa7b7d") ||
|
||
(ALabel2.Label.Id == "a45bd5c7-405d-4e58-8e59-35c98d74876b") ) // Top Secret <20><><EFBFBD>̺<EFBFBD><CCBA≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 24_1211 kku
|
||
{
|
||
nProcResult_ = 20;
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
nProcResult_ = 5;
|
||
|
||
if (ac.SetLabel(options))
|
||
{
|
||
nProcResult_ = 10;
|
||
}
|
||
else
|
||
{
|
||
nProcResult_ = 6;
|
||
}
|
||
|
||
|
||
// <20>Ʒ<EFBFBD>ó<EFBFBD><C3B3> <20>ϴϱ<CFB4>... 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȣȭ <20>Ǵ<EFBFBD> <20><><EFBFBD>찡 <20><EFBFBD><DFBB>Ѵ<EFBFBD>... HEC 24_0405 kku
|
||
// <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD>濡 <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD>찡 <20>־ <20>Ʒ<EFBFBD>ó<EFBFBD><C3B3> <20><><EFBFBD><EFBFBD> 24_0306 kku
|
||
//if (!ac.SetLabel(options))
|
||
//{
|
||
// nProcResult_ = 111;
|
||
// options.FileName = aEnt.src;
|
||
// options.OutputName = aEnt.dst + "_1";
|
||
// if (ac.RemoveProtection(options))
|
||
// {
|
||
// nProcResult_ = 112;
|
||
// options.FileName = aEnt.dst + "_1";
|
||
// options.OutputName = aEnt.dst;
|
||
// if (ac.SetLabel(options))
|
||
// {
|
||
// nProcResult_ = 10;
|
||
// }
|
||
// }
|
||
//}
|
||
//else nProcResult_ = 10;
|
||
}
|
||
}
|
||
break;
|
||
case 6:
|
||
if (hMod_ != IntPtr.Zero)
|
||
{
|
||
if ((DSCSIsEncryptedFile != null) && (DSCSDecryptFile != null))
|
||
{
|
||
if ((DSCSIsEncryptedFile(aEnt.src) == 1) && (DSCSDecryptFile(aEnt.src, aEnt.dst) == 1))
|
||
nProcResult_ = 10;
|
||
}
|
||
|
||
}
|
||
|
||
break;
|
||
case 7:
|
||
if (acNoD.RemoveLabel(options))
|
||
nProcResult_ = 10;
|
||
break;
|
||
}
|
||
}catch
|
||
{
|
||
// ...
|
||
//nProcResult_ = 0;
|
||
}
|
||
|
||
//Console.WriteLine("Result: " + nProcResult_ + " - Received " + msg.dwData + ": " + msg.lpData);
|
||
};
|
||
|
||
|
||
|
||
//mInstance.Text = mInstance.Handle.ToInt64().ToString();
|
||
|
||
while (true) // (IsOpen()) // IsOpen() <20>ϸ<EFBFBD> <20><DEB8> <20><EFBFBD><DFBB><EFBFBD> 23_1005 kku
|
||
{
|
||
Thread.Sleep(10);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Run the Catcher
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<BS1Aip> Start() {
|
||
Thread t = new Thread(runForm);
|
||
t.SetApartmentState(ApartmentState.STA);
|
||
t.IsBackground = true;
|
||
t.Start();
|
||
return await onLoad.Task.ConfigureAwait(false);
|
||
}
|
||
|
||
protected override void OnLoad(EventArgs e) {
|
||
base.OnLoad(e);
|
||
onLoad.SetResult(this);
|
||
}
|
||
|
||
public static IntPtr GetHandle() {
|
||
IntPtr val = IntPtr.Zero;
|
||
if (mInstance == null) throw new InvalidOperationException("Catcher not started");
|
||
mInstance.Invoke((MethodInvoker)delegate { val = mInstance.Handle; });
|
||
return val;
|
||
}
|
||
|
||
public static bool IsOpen() {
|
||
bool val = false;
|
||
if (mInstance == null) throw new InvalidOperationException("Catcher not started");
|
||
if (mInstance.IsDisposed || mInstance.Disposing)
|
||
return false;
|
||
try {
|
||
mInstance.Invoke((MethodInvoker)delegate { val = mInstance.Visible; });
|
||
}
|
||
catch {
|
||
return false;
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
public static void Stop() {
|
||
if (mInstance == null) throw new InvalidOperationException("Catcher not started");
|
||
DataCopied = null;
|
||
mInstance.Invoke(new MethodInvoker(mInstance.endForm));
|
||
}
|
||
|
||
private static void runForm() {
|
||
mInstance = new BS1Aip();
|
||
Application.Run(mInstance);
|
||
}
|
||
|
||
private void endForm() {
|
||
this.Close();
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
protected override void WndProc(ref Message m) {
|
||
if (m.Msg == NativeMethods.WM_COPYDATA) {
|
||
DataCopied?.Invoke(MessagePasser.ReceiveData(m));
|
||
StringCopied?.Invoke(MessagePasser.ReceiveString(m));
|
||
|
||
m.Result = new IntPtr(BS1Aip.nProcResult_);
|
||
} else
|
||
base.WndProc(ref m);
|
||
}
|
||
|
||
private void InitializeComponent()
|
||
{
|
||
this.SuspendLayout();
|
||
//
|
||
// BS1Aip
|
||
//
|
||
this.ClientSize = new System.Drawing.Size(284, 261);
|
||
this.Name = "BS1Aip";
|
||
this.ResumeLayout(false);
|
||
|
||
}
|
||
}
|
||
|
||
public static class NativeMethods {
|
||
public const int WM_COPYDATA = 0x004A;
|
||
|
||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref CopyData lParam);
|
||
|
||
[DllImport("user32")]
|
||
public static extern int RegisterWindowMessage(string message);
|
||
|
||
// TODO: possibly could send custom structs by changing CopyData.lpData to an IntPtr
|
||
public static IntPtr IntPtrAlloc<T>(T param) {
|
||
IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param));
|
||
Marshal.StructureToPtr(param, retval, false);
|
||
return retval;
|
||
}
|
||
|
||
public static void IntPtrFree(IntPtr preAllocated) {
|
||
if (IntPtr.Zero == preAllocated) throw new InvalidOperationException("IntPtr is already 0");
|
||
Marshal.FreeHGlobal(preAllocated);
|
||
preAllocated = IntPtr.Zero;
|
||
}
|
||
|
||
public static T GetStruct<T>(IntPtr param) {
|
||
return (T)Marshal.PtrToStructure(param, typeof(T));
|
||
}
|
||
|
||
public static IntPtr StringToIntPtr(string data) {
|
||
return Marshal.StringToHGlobalAnsi(data);
|
||
}
|
||
|
||
public static string IntPtrToString(IntPtr data) {
|
||
return Marshal.PtrToStringAnsi(data);
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// Pre-assembled class for sending/receiving strings between Windows applications.
|
||
/// </summary>
|
||
public static class MessagePasser {
|
||
/// <summary>
|
||
/// ReceiveData will throw if Message.Msg isn't WindowsMessageId
|
||
/// </summary>
|
||
public static bool ThrowOnBadMessage = true;
|
||
/// <summary>
|
||
/// Defaults to MS COPYDATA, can use NativeMethods.RegisterWindowMessage to create a new MessageId
|
||
/// </summary>
|
||
public static int WindowsMessageId = NativeMethods.WM_COPYDATA;
|
||
|
||
/// <summary>
|
||
/// Sends "data" to the target window
|
||
/// </summary>
|
||
/// <param name="targetWindowHandle"></param>
|
||
/// <param name="messageId">Usually WM_COPYDATA</param>
|
||
/// <param name="id"></param>
|
||
/// <param name="message"></param>
|
||
/// <returns></returns>
|
||
public static int SendData(IntPtr targetWindowHandle, int messageId, int id, string message) {
|
||
var data = new CopyData();
|
||
data.dwData = new IntPtr(id);
|
||
data.cbData = (message.Length + 1) * Marshal.SystemDefaultCharSize;
|
||
data.lpData = message;
|
||
|
||
var resp = NativeMethods.SendMessage(
|
||
targetWindowHandle,
|
||
messageId,
|
||
IntPtr.Zero,
|
||
ref data
|
||
);
|
||
var er = Marshal.GetLastWin32Error();
|
||
var errorMessage = new Win32Exception(er).Message;
|
||
if (er != 0)
|
||
throw new InvalidOperationException("Last Error isn't success:" + er + Environment.NewLine + errorMessage);
|
||
|
||
return resp.ToInt32();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Send a string with an id
|
||
/// </summary>
|
||
/// <param name="targetWindowHandle"></param>
|
||
/// <param name="id"></param>
|
||
/// <param name="message"></param>
|
||
/// <returns></returns>
|
||
public static int SendString(IntPtr targetWindowHandle, int id, string message) {
|
||
return SendData(targetWindowHandle, WindowsMessageId, id, message);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call to send a string with message type 1.
|
||
/// </summary>
|
||
/// <param name="targetWindowHandle"></param>
|
||
/// <param name="message"></param>
|
||
/// <returns></returns>
|
||
public static int SendString(IntPtr targetWindowHandle, string message) {
|
||
return SendString(targetWindowHandle, 1, message);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call this from WndProc to switch on dwData
|
||
/// </summary>
|
||
/// <param name="m"></param>
|
||
/// <returns></returns>
|
||
public static CopyData ReceiveData(Message m) {
|
||
if (m.Msg != WindowsMessageId) {
|
||
if (ThrowOnBadMessage)
|
||
throw new InvalidOperationException("Message isn't WM_COPYDATA");
|
||
return default(CopyData);
|
||
}
|
||
|
||
m.Result = new IntPtr(1);
|
||
var data = (CopyData)m.GetLParam(typeof(CopyData));
|
||
|
||
m.Result = new IntPtr(0);
|
||
|
||
return data;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Call this from WndProc if you don't care about message types
|
||
/// </summary>
|
||
/// <param name="m"></param>
|
||
/// <returns></returns>
|
||
public static string ReceiveString(Message m) {
|
||
return ReceiveData(m).lpData;
|
||
}
|
||
}
|
||
|
||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||
public struct CopyData {
|
||
/// <summary>
|
||
/// data to be passed, can be used as a message type identifier
|
||
/// </summary>
|
||
public IntPtr dwData;
|
||
/// <summary>
|
||
/// sizeof lpData
|
||
/// </summary>
|
||
public int cbData;
|
||
/// <summary>
|
||
/// data to be passed, can be null
|
||
/// </summary>
|
||
[MarshalAs(UnmanagedType.LPWStr)]
|
||
public string lpData;
|
||
}
|
||
}
|