Reputation: 2724
For a very peculiar requirement of a DLP software, I'm trying to detect OpenFileDialogs and cancel the file selection action, after capturing the selected file.
How am I trying to do this?
I put a global hook on the mouse and keyboard. I detect all actions that the user can perform to select a file in the OpenFileDialog window.
What I could not do until now is to detect if the window is an OpenFileDialog by hwnd.
Why am I trying this way?
I am a high level programmer and tried initially with windows hooks, without success. I tried with easyhook and deviare2. There seems to be no simpler way to put a global hook in a COM (IFileDialog) component call.
Is there any way to detect if a window is the default Windows OpenFileDialog window by hwnd?
public bool IsOpenFileDialog(IntPtr hwnd)
{
return ?
}
Upvotes: 1
Views: 1735
Reputation: 186668
As a partial solution (an adversary can mimic such a dialog), I suggest checking if the window a standard dialog and if it is, does it have "Save" in the caption (you can well put a better ctriterium here):
First, let's check class
:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx
using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int GetClassName(IntPtr hWnd,
StringBuilder lpClassName,
int nMaxCount);
private static String WndClassName(IntPtr handle) {
int length = 1024;
StringBuilder sb = new StringBuilder(length);
GetClassName(handle, sb, length);
return sb.ToString();
}
public static bool IsDialogClassName(IntPtr handle) {
// Standard windows dialogs like OpenFileDialog, SaveFileDialog have #32770 class name
return "#32770".Equals(WndClassName(handle));
}
However, it's too wide criterium: both Save File Dialog
and Open File Dialog
pass it. Let's check window's caption:
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd,
StringBuilder text,
int length);
private static String WindowText(IntPtr handle) {
int length = GetWindowTextLength(handle);
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(handle, sb, length + 1);
return sb.ToString();
}
public static bool IsSaveCaption(IntPtr handle) {
//TODO: put a better check for dialog's caption here
return WindowText(handle).IndexOf("Save", StringComparison.OrdinalIgnoreCase) >= 0;
}
Finally:
public bool IsOpenFileDialog(IntPtr hwnd) {
return IsDialogClassName(hwnd) &&
!IsSaveCaption(hwnd);
}
Sure you may want some other criteria, but I hope these two will be enough
Upvotes: 5