209 lines
7.7 KiB
Plaintext
209 lines
7.7 KiB
Plaintext
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
using DTS.Common.USBFramework;
|
|
using DTS.Common.Utilities.Logging;
|
|
|
|
namespace DTS.DASLib.DASFactory
|
|
{
|
|
internal abstract class WindowsNotification : DeviceHandling
|
|
{
|
|
protected FileIODeclarations.SECURITY_ATTRIBUTES Security;
|
|
protected DeviceManagement MyDeviceManagement;
|
|
|
|
protected Guid DeviceGuid = Guid.Empty;
|
|
|
|
/// <summary>
|
|
/// Handle of the window which receives messages from Windows. This will be a form.
|
|
/// </summary>
|
|
protected IntPtr RecipientHandle;
|
|
protected IntPtr DeviceNotifyHandle;
|
|
protected NotificationForm NotificationWindow;
|
|
|
|
protected WindowsNotification(DASFactory _factory,
|
|
UpdateFinishedEventHandler _SerialUpdateFinished,
|
|
Guid _guid,
|
|
BlockingCollection<Tuple<QueueActions, DeviceHandling>> queueActionPerDevice
|
|
)
|
|
: base(_factory, _SerialUpdateFinished, queueActionPerDevice)
|
|
{
|
|
MyDeviceManagement = new DeviceManagement();
|
|
Security = new FileIODeclarations.SECURITY_ATTRIBUTES
|
|
{
|
|
lpSecurityDescriptor = 0,
|
|
bInheritHandle = Convert.ToInt32(true)
|
|
};
|
|
Security.nLength = Marshal.SizeOf(Security);
|
|
|
|
DeviceGuid = _guid;
|
|
|
|
NotificationWindow = new NotificationForm(NotificationWndProc);
|
|
NotificationWindow.Show(); // will be hidden immediately
|
|
DeviceNotifyHandle = IntPtr.Zero;
|
|
RecipientHandle = NotificationWindow.Handle;
|
|
|
|
if (!MyDeviceManagement.RegisterForDeviceNotifications(RecipientHandle,
|
|
DeviceGuid,
|
|
ref DeviceNotifyHandle))
|
|
{
|
|
throw new Exception("DASFactory.WindowsNotification: Unable to register device");
|
|
}
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
if (DeviceNotifyHandle != IntPtr.Zero)
|
|
{
|
|
MyDeviceManagement.StopReceivingDeviceNotifications(DeviceNotifyHandle);
|
|
}
|
|
try
|
|
{
|
|
/*if (null != NotificationWindow)
|
|
{
|
|
if (NotificationWindow.InvokeRequired)
|
|
{
|
|
NotificationWindow.Invoke(new Action(() =>
|
|
{
|
|
if (NotificationWindow.IsHandleCreated)
|
|
{
|
|
NotificationWindow.Close();
|
|
NotificationWindow.Dispose();
|
|
NotificationWindow = null;
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
if (NotificationWindow.IsHandleCreated)
|
|
{
|
|
NotificationWindow.Close();
|
|
NotificationWindow.Dispose();
|
|
NotificationWindow = null;
|
|
}
|
|
}
|
|
}*/
|
|
/* Cross-thread operation not valid: Control 'NotificationForm' accessed from a thread other than the thread it was created on. */
|
|
//NotificationWindow.Close();
|
|
}
|
|
catch (Exception ex) { APILogger.Log(ex.Message); }
|
|
base.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// This gets called whenever anything happens to WinUSB devices
|
|
/// </summary>
|
|
/// <param name="m">The windows message</param>
|
|
protected virtual void NotificationWndProc(ref Message m)
|
|
{
|
|
//we detect the media arrival event
|
|
if (m.Msg != DeviceManagementDeclarations.WM_DEVICECHANGE)
|
|
{
|
|
return;
|
|
}
|
|
if (m.WParam.ToInt32() == DeviceManagementDeclarations.DBT_DEVICEARRIVAL)
|
|
{
|
|
if (Marshal.ReadInt32(m.LParam, 4) == DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE)
|
|
{
|
|
NotificationDeviceArrived(ref m);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m.WParam.ToInt32() == DeviceManagementDeclarations.DBT_DEVICEREMOVECOMPLETE)
|
|
{
|
|
if (Marshal.ReadInt32(m.LParam, 4) == DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE)
|
|
{
|
|
NotificationDeviceRemoved(ref m);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected abstract void NotificationDeviceArrived(ref Message m);
|
|
|
|
protected abstract void NotificationDeviceRemoved(ref Message m);
|
|
|
|
/// <summary>
|
|
/// Hidden Form which we use to receive Windows messages
|
|
/// </summary>
|
|
internal class NotificationForm : Form
|
|
{
|
|
public delegate void WinMsgProc(ref Message m);
|
|
|
|
private Label label1;
|
|
private readonly WinMsgProc mDetector;
|
|
|
|
/// <summary>
|
|
/// Set up the hidden form.
|
|
/// </summary>
|
|
/// <param name="detector">DriveDetector object which will receive notification about USB drives, see WndProc</param>
|
|
public NotificationForm(WinMsgProc detector)
|
|
{
|
|
mDetector = detector;
|
|
MinimizeBox = false;
|
|
MaximizeBox = false;
|
|
ShowInTaskbar = false;
|
|
ShowIcon = false;
|
|
FormBorderStyle = FormBorderStyle.FixedToolWindow;
|
|
Load += Load_Form;
|
|
Activated += Form_Activated;
|
|
}
|
|
|
|
private void Load_Form(object sender, EventArgs e)
|
|
{
|
|
// We don't really need this, just to display the label in designer ...
|
|
InitializeComponent();
|
|
|
|
// Create really small form, invisible anyway.
|
|
Size = new Size(5, 5);
|
|
}
|
|
|
|
private void Form_Activated(object sender, EventArgs e)
|
|
{
|
|
//this.Visible = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function receives all the windows messages for this window (form).
|
|
/// We call the DASFactory from here so that is can pick up the messages
|
|
/// </summary>
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
base.WndProc(ref m);
|
|
|
|
if (mDetector != null)
|
|
{
|
|
mDetector(ref m);
|
|
}
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
label1 = new Label();
|
|
SuspendLayout();
|
|
//
|
|
// label1
|
|
//
|
|
label1.AutoSize = true;
|
|
label1.Location = new Point(13, 30);
|
|
label1.Name = "label1";
|
|
label1.Size = new Size(314, 13);
|
|
label1.TabIndex = 0;
|
|
label1.Text = @"This is an invisible form.";
|
|
//
|
|
// DetectorForm
|
|
//
|
|
ClientSize = new Size(360, 80);
|
|
Controls.Add(label1);
|
|
Name = "NotificationForm";
|
|
Opacity = 0;
|
|
ResumeLayout(false);
|
|
PerformLayout();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|