/* =================== * 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(, "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 { /// /// A form to demonstrate WndProc CopyData /// 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 onLoad = new TaskCompletionSource(); 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; // ÀÛ¾÷Ç¥½ÃÁÙ¿¡¼­ ¼û±â±â this.Opacity = 0; // Æû ¼û±â±â, Åõ¸íµµ 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 ½ÇÆÐ .. 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 È­¸é¿¡¼­ ¼û±â±â 23_1204 kku //cp.ClassName = "BS1Aip"; //cp.Style |= 0x00000040; // BS_ICON value return cp; } } /// /// Creates a catcher window to demonstrate Message Passing /// 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 Ãß°¡, À§ÀÓ¾ÈÇÑ ³ôÀº ±ÇÇÑÀÌ ÇÊ¿äÇØ¼­.. ºñ¹Ð, ±Øºñµî ¾Ïȣȭ È®ÀÎ24_0723 kku //public static void RcvCmd(BSOneMip.Action ac) { Start().Wait(); //StringCopied += Console.WriteLine; DataCopied = msg => { try { AipEnt aEnt = JsonConvert.DeserializeObject(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 : ·¹À̺í ÃßÃâ, 1 : ¾Ïȣȭ, 2 : º¹È£È­, 3 : ¾Ïȣȭ È®ÀÎ, 4 : ·¹À̺í È®ÀÎ, 5 : ·¹ÀÌºí ¼³Á¤, 6 : ¼ÒÄ· º¹È£È­ { case 0: // ·¹À̺í ÃßÃâ if (ac.SaveLabelList(aEnt.src)) nProcResult_ = 10; break; case 1: // ¾Ïȣȭ if (ac.SetProtection(options)) nProcResult_ = 10; break; case 2: // º¹È£È­ if (ac.RemoveProtection(options)) nProcResult_ = 10; break; case 3: // ¾Ïȣȭ È®ÀÎ if (acNoD.IsProtection(aEnt.src)) nProcResult_ = 10; break; case 4: // ·¹À̺í È®ÀÎ 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: // ·¹ÀÌºí ¼³Á¤ // ·¹ÀÌºí ¼ÒÀ¯ÀÚ°¡ °°À»¶§¸¸ Àû¿ë kku, 23_1113 string sEmpNo = ac.GetEmpNo(); string sPxMail = aEnt.mail; // proxyAddress ó¸® Ãß°¡ 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; // ·¹À̺íÀÌ ÇöÀç¿Í ´Ù¸¦¶§¸¸ Àû¿ë kku, 23_1110 //options.LabelId = ""; ContentLabel ALabel2 = null; try { ALabel2 = ac.GetLabel(options); } catch { ALabel2 = null; } #if _HDENG_ if ((ALabel2 != null) && (ALabel2.Label != null)) { // ·¹À̺íÀÌ "ºñ¹Ð(Secret)"ÀÌ¸é ¹«½Ã 24_0527 kku if (ALabel2.Label.Id == "1bd401ce-2296-409e-b28d-ebe7aa124c57") { nProcResult_ = 22; return; } // ·¹À̺íÀÌ "±Øºñ(Top-Secret)"¸é ¹«½Ã 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") // ÀϹÝ_¹ÝÃâ¿ë (Public Release) { options.LabelId = "7c1e97b0-1625-488a-a30c-4f2188693461"; // ÀÏ¹Ý (General Purpose) } else if (ALabel2.Label.Id == "f2fa99e1-c17d-4934-9665-44d4df5ef1e6") // ´ë¿Üºñ_¹ÝÃâ¿ë (Confidential Release) { options.LabelId = "e7bd3a2c-b905-4bdb-8892-e6cd8d1eb00b"; // ´ë¿Üºñ (Confidential) } else if (ALabel2.Label.Id == "3fce3511-ace7-47a2-8106-f8bf1be7332b") // ±â¹Ð_¹ÝÃâ¿ë (Secret Release) { options.LabelId = "7d1539f9-8f3b-4cbd-b787-7ae1b30eae22"; // ±â¹Ð (Secret) } else if (ALabel2.Label.Id == "9f09d5d6-3008-4f6d-b4d3-c978a7d30f16") // ±Øºñ_¹ÝÃâ¿ë (Top Secret Release) { options.LabelId = "b40a7c1a-5443-458b-9215-2abda0acc4a4"; // ±Øºñ (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 ·¹À̺íÀÌ¸é ¹«½ÃÇÔ 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 ·¹À̺íÀÌ¸é ¹«½ÃÇÔ 24_1211 kku { nProcResult_ = 20; return; } } #endif nProcResult_ = 5; if (ac.SetLabel(options)) { nProcResult_ = 10; } else { nProcResult_ = 6; } // ¾Æ·¡Ã³·³ Çϴϱî... 2ÁßÀ¸·Î ¾Ïȣȭ µÇ´Â °æ¿ì°¡ ¹ß»ýÇÑ´Ù... HEC 24_0405 kku // ·¹ÀÌºí º¯°æ¿¡ ½ÇÆÐÇÏ´Â °æ¿ì°¡ À־ ¾Æ·¡Ã³·³ º¸¿Ï 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() ÇÏ¸é ¸Þ¸ð¸®¸¯ ¹ß»ýÇÔ 23_1005 kku { Thread.Sleep(10); } } /// /// Run the Catcher /// /// public static async Task 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(); } /// 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 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(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); } } /// /// Pre-assembled class for sending/receiving strings between Windows applications. /// public static class MessagePasser { /// /// ReceiveData will throw if Message.Msg isn't WindowsMessageId /// public static bool ThrowOnBadMessage = true; /// /// Defaults to MS COPYDATA, can use NativeMethods.RegisterWindowMessage to create a new MessageId /// public static int WindowsMessageId = NativeMethods.WM_COPYDATA; /// /// Sends "data" to the target window /// /// /// Usually WM_COPYDATA /// /// /// 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(); } /// /// Send a string with an id /// /// /// /// /// public static int SendString(IntPtr targetWindowHandle, int id, string message) { return SendData(targetWindowHandle, WindowsMessageId, id, message); } /// /// Call to send a string with message type 1. /// /// /// /// public static int SendString(IntPtr targetWindowHandle, string message) { return SendString(targetWindowHandle, 1, message); } /// /// Call this from WndProc to switch on dwData /// /// /// 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; } /// /// Call this from WndProc if you don't care about message types /// /// /// public static string ReceiveString(Message m) { return ReceiveData(m).lpData; } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct CopyData { /// /// data to be passed, can be used as a message type identifier /// public IntPtr dwData; /// /// sizeof lpData /// public int cbData; /// /// data to be passed, can be null /// [MarshalAs(UnmanagedType.LPWStr)] public string lpData; } }