c# receive plug and play events - c#

I was wondering if there are any examples and/or documentation on how to handle Plug and Play event messages used in Windows. Ideally what I am trying to accomplish is to be able to have my application detect a device that has been connected to a machine without having to have a timer, that on tick, will poll ALL COM ports. I find that doing this is extremely inefficient and ramps up my application's CPU usage ten fold. My application is in C# and is currently leveraging .NET 4.0 we are looking to upgrade to .NET 4.5 within the next month. So I am reaching out to find some kind of literature on how to do this. As this is my fist look into supporting a plug and play devices please be gentle with the criticism.
EDIT: Also this application will be running on Windows 7 and Windows XP

I've accomplished this in the past when writing a file browser by using a dummy HwndSource and adding an event handler via the HwndSource.AddHook() method.
// In object constructor
var hwndSource = new HwndSource(0, 0, 0, 0, 0, "", IntPtr.Zero); // Set up dummy HwndSource
hwndSource.AddHook(sourceHook);
IntPtr sourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg = WM_DEVICECHANGE)
if (wParam.ToInt32 == DBT_DEVICEARRIVAL) // Do what you need to do
if (wParam.ToInt32 == DBT_DEVICEREMOVALCOMPLETE) // Handle device removal
}
// Uses these defined constants:
private const int WM_DEVICECHANGE = 0x219;
private const int DBT_DEVICEARRIVAL = 0x8000;
private const int DBT_DEVICEREMOVALCOMPLETE = 0x8004;
The MSDN for WM_DEVICECHANGE also has info for other const definitions that may be useful:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363480(v=vs.85).aspx

Related

Can Keylogger apps able to see the messages sent via SendMessage()?

I am creating a c# app to send a message in a notepad using the SendMessage() function. I have successfuly passed the strings to notepad. The strings are very important and i was wondering if a keylogger program can see this message?
If yes, do you have any other ideas on how i can send the strings securely?
Below is a sample code i used.
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
Process[] notepads = Process.GetProcessesByName("notepad");
if (notepads.Length == 0) return;
if (notepads[0] != null)
{
IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
SendMessage(child, 0x000C, 0, TextBox1.Text);
}
What you're doing is not secure; there are multiple ways a SendMessage call can be spied on by anyone who wants to do so.
SetWindowsHookEx with WH_CALLWNDPROC or WH_CALLWNDPROCRET will let an attacker monitor all messages being sent to a given thread, or they can monitor all messages across the system and just filter out the ones headed to your SendMessage target.
Alternately, an attacker can inject themselves into your recipient process, using WriteProcessMemory to write a DLL name into the recipient process, then CreateRemoteThread and LoadLibrary to load the DLL into the target process. After that, monitoring the process's messages should be fairly trivial.
To avoid using a DLL, an attacker could also use WriteProcessMemory to write code directly into the target process's memory space, then CreateRemoteThread to call it.
All three of these monitoring methods are documented in this CodeProject article. It's admittedly a little old, but the methods should still be relevant, particularly the SetWindowsHookEx one.
An attacker could also hook various Windows APIs directly; it's difficult and somewhat risky, but depending on the sensitivity of your data an attacker might find it a worthwhile approach.
Trying to protect your data will be very difficult, honestly. You can look at how KeePass keeps passwords secure; it's got a setting (at least in the 1.x branch; KeePass 2.x is an entirely different app) to "allow pasting only once and protect against clipboard spies", which might be of some benefit to you. Taking another cue from KeePass, you can also look into Windows' Data Protection API.
As a side note, you may want to replace
SendMessage(child, 0x000C, 0, TextBox1.Text);
with
SendMessage(child, WM_SETTEXT, 0, TextBox1.Text);
for readability. Not many people will recognize 0x000C by itself, although it's possible to guess what the message is based on context.

Prevent Citrix session to timeout

I need some applications running overnight on Citrix. I don't wish to stay awake all night for that. The Session will timeout and application will be closed. I would not convince the administrator to change the Citrix configuration for this application.
I am trying to create application which will periodically send mouse or keyboard events to the Citrix window. I already have a simple solution which is clicking the mouse.
I wish to have a better solution where everything will be done on background and events would be send just to the Citrix window. Any ideas how to achieve that?
I am using Windows and C# with .NET.
Thank you for any help.
Update #1
I am trying to use Citrix Live Monitoring API as it appears to be a best option. I end up with this:
WFICALib.ICAClient ico = new WFICALib.ICAClient();
int enumHandle = ico.EnumerateCCMSessions();
Console.WriteLine(ico.GetErrorMessage(ico.GetLastError()));
Unfortunately this returns an error message saying:
Live monitoring is disabled
According to documentation it requires following registry keys to be set to 1:
"HKLM\Software\Citrix\ICA Client\CCM\AllowLiveMonitoring(REG_DWORD)"
Problem is that I was unable to find Citrix key in "HKLM\Software\" and it also don't work if I created this keys and values. How do I enable Live Monitoring API?
I have played around with sending input to other windows in the past. I used something like the following:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private static void LeftMouseClick(Point point)
{
int xpos = (int)point.X;
int ypos = (int)point.Y;
if (SetCursorPos(xpos, ypos))
{
mouse_event(MOUSEEVENTF_LEFTDOWN, xpos, ypos, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, xpos, ypos, 0, 0);
}
}
So to make this work you need to inject coordinates that fall within the Citrix Receiver window. I can't recall whether you get any focus/activation issues - I believe the click injection should bring the window into focus. I never did anything particularly serious with this code so no guarantees.

How to detect when the user switches to the Log On screen?

I need to know when the user switches to the logon screen (as triggered by ctrl-alt-del) in order to circumvent a pesky bug in WPF. I want to work around this bug by reinitializing my GUI after returning from the logon screen. Currently it works, but I have to trigger it manually.
I have found SystemEvents.SessionSwitch, but unfortunately this is only triggered when logging off.
How can I detect when the logon screen is displayed by forming ctrl-alt-del?
The tricky thing is that this is not a session change, but rather just a desktop change. In particular, Ctrl+Alt+Del switches to a secured desktop associated with Winlogon.
I don't think you're really supposed to detect this kind of thing (that is, after all, the whole point of having a "secure desktop"), but you could probably do it using an Active Accessibility hook. Call the SetWinEventHook function to install an event hook for the EVENT_SYSTEM_DESKTOPSWITCH event and see what notifications you receive.
To get it going, you'll need to do the following:
Ensure that you're pumping a message loop on your client thread in order to receive event notifications. This shouldn't be a problem for a standard WPF application.
Make sure that you specify the WINEVENT_OUTOFCONTEXT flag, considering that you're working from managed code. You don't want the system to attempt to inject your DLL that contains the callback function into every process. Instead, this will cause the callback function to be called asynchronously from a queue; much safer from the land of managed code.
A little bit of P/Invoke magic. To get you started…
const uint WINEVENT_OUTOFCONTEXT = 0x0;
const uint EVENT_SYSTEM_DESKTOPSWITCH = 0x0020;
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin,
uint eventMax,
IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc,
uint idProcess,
uint idThread,
uint dwFlags);
delegate void WinEventDelegate(IntPtr hWinEventHook,
uint event,
IntPtr hwnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime);
[DllImport("user32.dll")]
static extern bool UnhookWinEvent(IntPtr hWinEventHook);
The process which gets started to show the logon screen seems to be called LogonUI.exe.
Using the Windows Management Instrumentation (WMI) infrastructure you can listen for processes which start and shut down. You will need to reference the System.Management assembly.
var interval = new TimeSpan( 0, 0, 1 );
const string isWin32Process = "TargetInstance isa \"Win32_Process\"";
// Listen for started processes.
WqlEventQuery startQuery
= new WqlEventQuery( "__InstanceCreationEvent", interval, isWin32Process );
_startWatcher = new ManagementEventWatcher( startQuery );
_startWatcher.Start();
_startWatcher.EventArrived += OnStartEventArrived;
// Listen for closed processes.
WqlEventQuery stopQuery
= new WqlEventQuery( "__InstanceDeletionEvent", interval, isWin32Process );
_stopWatcher = new ManagementEventWatcher( stopQuery );
_stopWatcher.Start();
_stopWatcher.EventArrived += OnStopEventArrived;
Handling these events, you can get information about the started or closed process. This way you can verify when LogonUI.exe was shut down, and subsequently trigger the required actions.
void OnStopEventArrived( object sender, EventArrivedEventArgs e )
{
var o = (ManagementBaseObject)e.NewEvent[ "TargetInstance" ];
string name = (string)o[ "Name" ];
...
}

Artificially generate key events in other programs

Can a C# program that has focus artificially generate a key event that will be handled by another open application?
For those who are curious, this is why I'm asking:
I'm currently working on a demo/mockup for a design idea for a gesture based media player, using the Kinect as a primary input device. This is something I decided to do on as a favor, and it neither needs nor deserves a ton of my time as far as programming goes.
So to speed things along, I'm using the FAAST tool which you can use to easily bind key events to certain gestures. So, you turn on this program, tell it what key maps to what gesture, then when you make the gesture the key is registered as pressed by the current application.
What I would like to create is a go-between that will display a simple GUI that I'll display to the audience. At a certain point, the user will make the "select" gesture, and I want music to start playing in an open media player. So, I would check their place in the menu hierarchy, see that they've selected "music" based on some key I choose to arbitrarily mean select, then generate a key event with the MediaPlayPause key.
It requires a little p/invoke work to do from C# but it's not complicated. You'll use the FindWindow API to get an hWnd for the target program, then the PostMessage API to send key events:
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private const UInt32 WM_KEYDOWN = 0x0100;
private const UInt32 WM_KEYUP = 0x0101;
public static void SendSelect(IntPtr HWnd)
{
PostMessage(HWnd, WM_KEYDOWN, KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.Enter), 0);
}

How do I prevent print screen

I have a requirement that an application I am working on prevent the user from being able to easily capture the contents of the screen.
I have communicated that there is no feasible way to completely prevent this from happening, but I'm looking for methods to introduce some hurdles to the process.
I'm using C#/.NET 2.0 and WinForms
You can't.
The best you can do is render to a hardware accelerated device on an overlay, similar to what video players used to do. Basically, you paint your entire window blue, and render your graphics onto the video card, and internally the video card will replace the blue with the graphics. The downside to this is you have to give up using winforms controls, and I don't know of any way to do this with .NET easily. I think if you use DirectShow.NET, one of their samples is putting your own graphics into a stream.
Even after doing all of that, it's still possible to get a screenshot. Just take a picture of the screen with a digital camera.
From here:
A. Windows implements Print Screen using a registered hotkey. Windows
uses the predefined hotkeys IDHOT_SNAPDESKTOP and IDHOT_SNAPWINDOW to
handle Print Screen. These correspond to Print Screen, which captures
the entire screen, and Alt+Print Screen, which captures only the
active window. To disable these functions all you have to do is
register the hotkeys, which causes Windows to send your app a
WM_HOTKEY message when the user presses either hotkey. Your
implementation can ignore the message to bypass the default
screen-capture behavior. A good place to do it is in your mainframe
class.
FWIW, it is possible. Here's some code:
This would be a dll that you create, then call the HookKeyboard method from your application. I've tested it and it works. Granted, if someone takes a picture with a camera it can't help, but, point made. NYAH!
namespace KeyboardHook
{
public class Hooker
{
[StructLayout(LayoutKind.Sequential)]
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time
;
public int extraInfo;
}
public delegate int HookProc(int nCode, int wParam, IntPtr ptrKBDLLHOOKSTRUCT);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc callBack, IntPtr hMod, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int CallNextHookEx(IntPtr hhk, int nCode, int wParam, IntPtr lParam);
private static IntPtr kbh_Handle;
private static HookProc kbh_HookProc;
private const int VK_SNAPSHOT = 0x2C;
private const int WM_KEYDOWN = 0x0100;
private const int WM_SYSKEYDOWN = 0x0104;
private const int WH_KEYBOARD_LL = 13;
private static int LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode < 0)
{
CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
return 0;
}
if (wParam == WM_KEYDOWN)
{
IntPtr kbdll = lParam;
KBDLLHOOKSTRUCT kbdllstruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(kbdll, typeof(KBDLLHOOKSTRUCT));
if (kbdllstruct.vkCode == VK_SNAPSHOT)
return -1;
}
return CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
}
public static void HookKeyboard()
{
try
{
kbh_HookProc = LowLevelKeyboardProc;
kbh_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, kbh_HookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
if (kbh_Handle != IntPtr.Zero)
System.Diagnostics.Debug.WriteLine(String.Format("It worked! HookHandle: {0}", kbh_Handle));
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(String.Format("ERROR: {0}", ex.Message));
}
}
}
}
You can try using IpcProtectWindow provided in msipc.dll.
[DllImport("msipc.dll", SetLastError = false, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int IpcProtectWindow([In] IntPtr hwnd);
Download the SDK from Microsoft
Call the function above and provide the handle of the form you would like to protect. (Form.Handle property)
You'll have two cases here that you need to worry about. One, when your window/application has focus, the other when it doesn't have focus.
When it doesn't have focus, there's not a whole lot you can do, i.e. if the user clicks off of your app and onto the desktop, keys aren't sent to your app so you'll never see them. In that case, you can minimize to the tray when your app loses focus (or, perhaps, place a "blank" panel over the form to prevent users from seeing anything on it which will also prevent a print-screen from being useful).
In the other case, when you have focus, capture keystrokes and examine them. If the Alt key is down and the PrintScreen key is down, reset the value so that a print-screen doesn't occur. (Come to think of it, that may not work. I'd need to test it to be sure.)
You could look into what movie players do. I believe they render directly to a hardware surface (via DirectX). I suspect that you'd need to do this.
This doesn't really answer the questions, but keep in mind that there exists tools to capture screen, and that a simple camera breaks everything.
I mean ok you "have to", but I would (but I'm young and still student, so I don't know much about what can be said) answer that this is just stupid.
Check out the new tech - sivizion.com, they prevent print screen all together - no way to bypass it. If anyone will figure out a way how to hack it, please post here, I couldn't. I think they also license their tech, not sure, check it out.
Well, you could try capturing the button, but I'm not sure how well that will work.
One thing that always annoyed me was that whenever I played a movie, it would never take screenshots of it. If you can render through a separate context, it would make it really annoying to take a picture of it. Perhaps you can send your screen output through something like that?
There are applications that can capture the screen from OpenGL and DirectX apps ! (depending (they are used for recording game movies)
ps. windows aero is DirectX
http://www.fraps.com/
i think thats the application
You can make any casual Print Screen useless using Visual Cryptography and taking advantage of retinal persistence (see this article for details, and bit.ly/vcrypto for a web demo).
The idea is to alternate at high frequency between two or more random noise images, that will combine through persistence of vision to reveal the content. A screen capture will only grab one image, with meaningless random noise.
This comes at the cost of flickering and inducing user headaches, can be defeated by a camera taking a picture of the screen, or by a less casual user that knows photoshop, but will defeat any kind of casual screen capture or frame grabbing.
Might occasionally be useful, in an academic meaning of the term!
It is too late but there is a quick work around,
Simply use it in MDI form
Set TopMost Property of form True, then write below event
private void frmMDI_Deactivate(object sender, EventArgs e){Clipboard.Clear();}
after taking print screen user have to minimize the application, the moment user minimize the app, we are clearing clipboard.
you can use this in logout function or when screen move or resize or any other form event as required :)
Snipping tool also can't copy screens by this if TopMost Property is true.
Yes we can't stop user from capturing screen from external device like phone or cam.
In windows form application, Use this code in form keyup event,
if (e.KeyCode == Keys.PrintScreen)
{
Clipboard.Clear();
}
Form keypreview should be TRUE
Microsoft has been developed an API named SetWindowDisplayAffinity to support the window content protection. This feature enables applications to protect application content from being captured or copied through a specific set of public operating system features and APIs
SetWindowDisplayAffinity(hWnd, WDA_MONITOR);
I solved it using a Timer object and Clipboard.Clear() method.
First add a Timer to your main form with Interval=1 (Very fast), then add the following code in its event:
Clipboard.Clear();

Categories

Resources