From: <an...@us...> - 2007-07-05 04:48:34
|
Revision: 671 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=671&view=rev Author: and-81 Date: 2007-07-04 21:48:31 -0700 (Wed, 04 Jul 2007) Log Message: ----------- Modified Paths: -------------- trunk/plugins/IR Server Suite/Applications/Debug Client/MainForm.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs trunk/plugins/IR Server Suite/IR Server Plugins/XBCDRC Receiver/XBCDRC Receiver.cs trunk/plugins/IR Server Suite/IR Server Suite.sln Added Paths: ----------- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.Designer.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.resx trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.csproj trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/DeviceSelect.Designer.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/DeviceSelect.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/DeviceSelect.resx trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/NativeMethods.cs trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Properties/ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Properties/AssemblyInfo.cs Modified: trunk/plugins/IR Server Suite/Applications/Debug Client/MainForm.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Debug Client/MainForm.cs 2007-07-03 20:43:01 UTC (rev 670) +++ trunk/plugins/IR Server Suite/Applications/Debug Client/MainForm.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -165,7 +165,7 @@ { PipeMessage received = PipeMessage.FromString(message); - this.Invoke(_AddStatusLine, new Object[] { received.Name }); + this.Invoke(_AddStatusLine, new Object[] { String.Format("Received Message: \"{0}\"", received.Name) }); try { @@ -357,7 +357,7 @@ } void RemoteButtonPressed(string keyCode) { - string text = String.Format(" - {0}", keyCode); + string text = String.Format("Remote Button \"{0}\"", keyCode); this.Invoke(_AddStatusLine, new Object[] { text }); } Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs 2007-07-03 20:43:01 UTC (rev 670) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -33,9 +33,9 @@ this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripComboBoxSkin = new System.Windows.Forms.ToolStripComboBox(); this.changeServerHostToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItemHelp = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItemQuit = new System.Windows.Forms.ToolStripMenuItem(); this.labelDisabled = new System.Windows.Forms.Label(); - this.toolStripMenuItemHelp = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuStrip.SuspendLayout(); this.SuspendLayout(); // @@ -50,7 +50,7 @@ this.contextMenuStrip.Name = "contextMenuStrip"; this.contextMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; this.contextMenuStrip.ShowImageMargin = false; - this.contextMenuStrip.Size = new System.Drawing.Size(156, 117); + this.contextMenuStrip.Size = new System.Drawing.Size(156, 95); // // toolStripComboBoxSkin // @@ -68,6 +68,13 @@ this.changeServerHostToolStripMenuItem.ToolTipText = "Change the address of the server host"; this.changeServerHostToolStripMenuItem.Click += new System.EventHandler(this.changeServerHostToolStripMenuItem_Click); // + // toolStripMenuItemHelp + // + this.toolStripMenuItemHelp.Name = "toolStripMenuItemHelp"; + this.toolStripMenuItemHelp.Size = new System.Drawing.Size(155, 22); + this.toolStripMenuItemHelp.Text = "Help"; + this.toolStripMenuItemHelp.Click += new System.EventHandler(this.toolStripMenuItemHelp_Click); + // // toolStripMenuItemQuit // this.toolStripMenuItemQuit.Name = "toolStripMenuItemQuit"; @@ -90,13 +97,6 @@ this.labelDisabled.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.labelDisabled.Visible = false; // - // toolStripMenuItemHelp - // - this.toolStripMenuItemHelp.Name = "toolStripMenuItemHelp"; - this.toolStripMenuItemHelp.Size = new System.Drawing.Size(155, 22); - this.toolStripMenuItemHelp.Text = "Help"; - this.toolStripMenuItemHelp.Click += new System.EventHandler(this.toolStripMenuItemHelp_Click); - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs 2007-07-03 20:43:01 UTC (rev 670) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -19,30 +19,12 @@ public partial class MainForm : Form { - #region Constants - - const string DefaultSkin = "MCE"; - - public static readonly string ConfigurationFile = Common.FolderAppData + "Virtual Remote\\Virtual Remote.xml"; - - #endregion Constants - #region Variables - bool _registered = false; - bool _keepAlive = true; - int _echoID = -1; - Thread _keepAliveThread; + RemoteButton []_buttons; - string _serverHost; - string _localPipeName; - string _lastKeyCode = String.Empty; - string _remoteSkin; + Thread _updateThread; - string _installFolder; - - RemoteButton[] _buttons = null; - #endregion Variables #region Constructor @@ -50,48 +32,24 @@ public MainForm() { InitializeComponent(); - - _setLabel = new DelegateSetLabel(SetLabel); } #endregion Constructor private void MainForm_Load(object sender, EventArgs e) { - IrssLog.LogLevel = IrssLog.Level.Debug; - IrssLog.Open(Common.FolderIrssLogs + "Virtual Remote.log"); + SetSkinList(); + SetSkin(Program.RemoteSkin); - IrssLog.Debug("Platform is {0}", (IntPtr.Size == 4 ? "32-bit" : "64-bit")); - - LoadSettings(); - - IrssUtils.Forms.ServerAddress serverAddress; - - if (String.IsNullOrEmpty(_serverHost)) - { - serverAddress = new IrssUtils.Forms.ServerAddress(Environment.MachineName); - serverAddress.ShowDialog(this); - _serverHost = serverAddress.ServerHost; - } - - if (StartComms()) - { - SetSkinList(); - SetSkin(_remoteSkin); - } - else - { - Application.Exit(); - } + _updateThread = new Thread(new ThreadStart(SetLabel)); + _updateThread.Start(); } + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { - SaveSettings(); - - StopComms(); - - IrssLog.Close(); + _updateThread.Abort(); } + private void MainForm_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) @@ -127,112 +85,6 @@ } } - void LoadSettings() - { - try - { - _installFolder = SystemRegistry.GetInstallFolder(); - if (String.IsNullOrEmpty(_installFolder)) - _installFolder = "."; - else - _installFolder += "\\Virtual Remote"; - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - - _installFolder = "."; - } - - try - { - XmlDocument doc = new XmlDocument(); - doc.Load(ConfigurationFile); - - _serverHost = doc.DocumentElement.Attributes["ServerHost"].Value; - _remoteSkin = doc.DocumentElement.Attributes["RemoteSkin"].Value; - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - - _serverHost = String.Empty; - _remoteSkin = DefaultSkin; - } - } - void SaveSettings() - { - try - { - XmlTextWriter writer = new XmlTextWriter(ConfigurationFile, System.Text.Encoding.UTF8); - writer.Formatting = Formatting.Indented; - writer.Indentation = 1; - writer.IndentChar = (char)9; - writer.WriteStartDocument(true); - writer.WriteStartElement("settings"); // <settings> - - writer.WriteAttributeString("ServerHost", _serverHost); - writer.WriteAttributeString("RemoteSkin", _remoteSkin); - - writer.WriteEndElement(); // </settings> - writer.WriteEndDocument(); - writer.Close(); - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - } - } - - bool StartComms() - { - try - { - if (OpenLocalPipe()) - { - _keepAliveThread = new Thread(new ThreadStart(KeepAliveThread)); - _keepAliveThread.Start(); - return true; - } - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - } - - return false; - } - void StopComms() - { - _keepAlive = false; - - try - { - if (_keepAliveThread != null && _keepAliveThread.IsAlive) - _keepAliveThread.Abort(); - } - catch { } - - try - { - if (_registered) - { - _registered = false; - - PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Unregister", null); - PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); - } - } - catch { } - - try - { - if (PipeAccess.ServerRunning) - PipeAccess.StopServer(); - } - catch { } - } - bool LoadSkinXml(string xmlFile) { if (!File.Exists(xmlFile)) @@ -278,14 +130,14 @@ { try { - string[] skins = Directory.GetFiles(_installFolder + "\\Skins\\", "*.png", SearchOption.TopDirectoryOnly); + string[] skins = Directory.GetFiles(Program.InstallFolder + "\\Skins\\", "*.png", SearchOption.TopDirectoryOnly); for (int index = 0; index < skins.Length; index++) skins[index] = Path.GetFileNameWithoutExtension(skins[index]); toolStripComboBoxSkin.Items.Clear(); toolStripComboBoxSkin.Items.AddRange(skins); - toolStripComboBoxSkin.SelectedItem = _remoteSkin; + toolStripComboBoxSkin.SelectedItem = Program.RemoteSkin; } catch (Exception ex) { @@ -300,17 +152,17 @@ if (String.IsNullOrEmpty(skin)) return; - string skinFile = String.Format("{0}\\Skins\\{1}.png", _installFolder, skin); + string skinFile = String.Format("{0}\\Skins\\{1}.png", Program.InstallFolder, skin); if (!File.Exists(skinFile)) throw new FileNotFoundException("Skin graphic file not found", skin); // Try to load xml file of same name, failing that load using first word of skin name ... - string xmlFile = String.Format("{0}\\Skins\\{1}.xml", _installFolder, skin); + string xmlFile = String.Format("{0}\\Skins\\{1}.xml", Program.InstallFolder, skin); if (!File.Exists(xmlFile)) { string firstWord = skin.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; - xmlFile = String.Format("{0}\\Skins\\{1}.xml", _installFolder, firstWord); + xmlFile = String.Format("{0}\\Skins\\{1}.xml", Program.InstallFolder, firstWord); if (!File.Exists(xmlFile)) throw new FileNotFoundException("Skin file not found", xmlFile); @@ -320,7 +172,7 @@ { this.BackgroundImage = new Bitmap(skinFile); this.ClientSize = new System.Drawing.Size(this.BackgroundImage.Width, this.BackgroundImage.Height); - _remoteSkin = skin; + Program.RemoteSkin = skin; } else throw new Exception(String.Format("Failed to load skin file not found \"{0}\"", xmlFile)); @@ -336,265 +188,19 @@ if (!PipeAccess.ServerRunning) return; - PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Forward Remote Button", Encoding.ASCII.GetBytes(keyCode)); - PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + PipeMessage message = new PipeMessage(Program.LocalPipeName, Environment.MachineName, "Forward Remote Button", Encoding.ASCII.GetBytes(keyCode)); + PipeAccess.SendMessage(Common.ServerPipeName, Program.ServerHost, message.ToString()); } - bool OpenLocalPipe() + void SetLabel() { - try + while (true) { - int pipeNumber = 1; - bool retry = false; - - do - { - string localPipeTest = String.Format(Common.LocalPipeFormat, pipeNumber); - - if (PipeAccess.PipeExists(String.Format("\\\\.\\pipe\\{0}", localPipeTest))) - { - if (++pipeNumber <= Common.MaximumLocalClientCount) - retry = true; - else - throw new Exception(String.Format("Maximum local client limit ({0}) reached", Common.MaximumLocalClientCount)); - } - else - { - if (!PipeAccess.StartServer(localPipeTest, new PipeMessageHandler(ReceivedMessage))) - throw new Exception(String.Format("Failed to start local pipe server \"{0}\"", localPipeTest)); - - _localPipeName = localPipeTest; - retry = false; - } - } - while (retry); - - return true; + labelDisabled.Visible = !Program.Registered; + Thread.Sleep(2500); } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - return false; - } } - bool ConnectToServer() - { - try - { - PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Register", null); - PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); - return true; - } - catch (AppModule.NamedPipes.NamedPipeIOException) - { - return false; - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - return false; - } - } - - void KeepAliveThread() - { - Random random = new Random((int)DateTime.Now.Ticks); - bool reconnect; - int attempt; - - _registered = false; - _keepAlive = true; - while (_keepAlive) - { - reconnect = true; - - this.Invoke(_setLabel, new Object[] { true }); - - #region Connect to server - - IrssLog.Info("Connecting ({0}) ...", _serverHost); - attempt = 0; - while (_keepAlive && reconnect) - { - if (ConnectToServer()) - { - reconnect = false; - } - else - { - int wait; - - if (attempt <= 50) - attempt++; - - if (attempt > 50) - wait = 30; // 30 seconds - else if (attempt > 20) - wait = 10; // 10 seconds - else if (attempt > 10) - wait = 5; // 5 seconds - else - wait = 1; // 1 second - - for (int sleeps = 0; sleeps < wait && _keepAlive; sleeps++) - Thread.Sleep(1000); - } - } - - #endregion Connect to server - - #region Wait for registered - - // Give up after 10 seconds ... - attempt = 0; - while (_keepAlive && !_registered && !reconnect) - { - if (++attempt >= 10) - reconnect = true; - else - Thread.Sleep(1000); - } - - #endregion Wait for registered - - #region Registered ... - - if (_keepAlive && _registered && !reconnect) - { - IrssLog.Info("Connected ({0})", _serverHost); - - this.Invoke(_setLabel, new Object[] { false }); - } - - #endregion Registered ... - - #region Ping the server repeatedly - - while (_keepAlive && _registered && !reconnect) - { - int pingID = random.Next(); - long pingTime = DateTime.Now.Ticks; - - try - { - PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Ping", BitConverter.GetBytes(pingID)); - PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); - } - catch - { - // Failed to ping ... reconnect ... - IrssLog.Warn("Failed to ping, attempting to reconnect ..."); - _registered = false; - reconnect = true; - break; - } - - // Wait 10 seconds for a ping echo ... - bool receivedEcho = false; - while (_keepAlive && _registered && !reconnect && - !receivedEcho && DateTime.Now.Ticks - pingTime < 10 * 1000 * 10000) - { - if (_echoID == pingID) - { - receivedEcho = true; - } - else - { - Thread.Sleep(1000); - } - } - - if (receivedEcho) // Received ping echo ... - { - // Wait 60 seconds before re-pinging ... - for (int sleeps = 0; sleeps < 60 && _keepAlive && _registered; sleeps++) - Thread.Sleep(1000); - } - else // Didn't receive ping echo ... - { - IrssLog.Warn("No echo to ping, attempting to reconnect ..."); - - // Break out of pinging cycle ... - _registered = false; - reconnect = true; - } - } - - #endregion Ping the server repeatedly - - } - - } - - delegate void DelegateSetLabel(bool visible); - DelegateSetLabel _setLabel = null; - - void SetLabel(bool visible) - { - labelDisabled.Visible = visible; - } - - void ReceivedMessage(string message) - { - PipeMessage received = PipeMessage.FromString(message); - - IrssLog.Debug("Received Message \"{0}\"", received.Name); - - try - { - switch (received.Name) - { - case "Remote Button": - break; - - case "Register Success": - { - IrssLog.Info("Registered to IR Server"); - _registered = true; - //_transceiverInfo = TransceiverInfo.FromBytes(received.Data); - break; - } - - case "Register Failure": - { - IrssLog.Warn("IR Server refused to register"); - _registered = false; - break; - } - - case "Server Shutdown": - { - IrssLog.Warn("IR Server Shutdown - Tray Launcher disabled until IR Server returns"); - _registered = false; - break; - } - - case "Echo": - { - _echoID = BitConverter.ToInt32(received.Data, 0); - break; - } - - case "Error": - { - IrssLog.Error(Encoding.ASCII.GetString(received.Data)); - break; - } - - default: - { - IrssLog.Warn("Unknown message received from server: " + received.Name); - break; - } - } - } - catch (Exception ex) - { - IrssLog.Error(ex.ToString()); - } - } - private void toolStripMenuItemQuit_Click(object sender, EventArgs e) { IrssLog.Info("User quit"); @@ -610,13 +216,13 @@ private void changeServerHostToolStripMenuItem_Click(object sender, EventArgs e) { - StopComms(); + Program.StopComms(); - IrssUtils.Forms.ServerAddress serverAddress = new IrssUtils.Forms.ServerAddress(_serverHost); + IrssUtils.Forms.ServerAddress serverAddress = new IrssUtils.Forms.ServerAddress(Program.ServerHost); serverAddress.ShowDialog(this); - _serverHost = serverAddress.ServerHost; + Program.ServerHost = serverAddress.ServerHost; - StartComms(); + Program.StartComms(); } private void toolStripMenuItemHelp_Click(object sender, EventArgs e) Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-07-03 20:43:01 UTC (rev 670) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -1,23 +1,531 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Text; +using System.Threading; using System.Windows.Forms; +using System.Xml; +using NamedPipes; +using IrssUtils; + namespace VirtualRemote { static class Program { + #region Constants + + const string DefaultSkin = "MCE"; + + public static readonly string ConfigurationFile = Common.FolderAppData + "Virtual Remote\\Virtual Remote.xml"; + + #endregion Constants + + #region Variables + + static bool _registered = false; + static bool _keepAlive = true; + static int _echoID = -1; + static Thread _keepAliveThread; + + static string _serverHost; + static string _localPipeName; + static string _lastKeyCode = String.Empty; + + static string _installFolder; + + static string _remoteSkin; + + #endregion Variables + + #region Properties + + internal static bool Registered + { + get { return _registered; } + } + + internal static string ServerHost + { + get { return _serverHost; } + set { _serverHost = value; } + } + + internal static string LocalPipeName + { + get { return _localPipeName; } + } + + internal static string InstallFolder + { + get { return _installFolder; } + } + + internal static string RemoteSkin + { + get { return _remoteSkin; } + set { _remoteSkin = value; } + } + + #endregion Properties + /// <summary> /// The main entry point for the application. /// </summary> [STAThread] - static void Main() + static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm()); + + IrssLog.LogLevel = IrssLog.Level.Debug; + IrssLog.Open(Common.FolderIrssLogs + "Virtual Remote.log"); + + IrssLog.Debug("Platform is {0}", (IntPtr.Size == 4 ? "32-bit" : "64-bit")); + + LoadSettings(); + + if (args.Length > 0) // Command Line Start ... + { + List<String> virtualButtons = new List<string>(); + + try + { + for (int index = 0; index < args.Length; index++) + { + if (args[index].Equals("-host", StringComparison.InvariantCultureIgnoreCase)) + { + _serverHost = args[++index]; + continue; + } + else + { + virtualButtons.Add(args[index]); + } + } + } + catch (Exception ex) + { + IrssLog.Error("Error processing command line parameters: {0}", ex.Message); + } + + if (virtualButtons.Count != 0 && StartComms()) + { + Thread.Sleep(250); + + // Wait for registered ... Give up after 10 seconds ... + int attempt = 0; + while (!_registered) + { + if (++attempt >= 10) + break; + else + Thread.Sleep(1000); + } + + if (_registered) + { + foreach (String button in virtualButtons) + { + if (button.StartsWith("~")) + { + Thread.Sleep(button.Length * 500); + } + else + { + PipeMessage message = new PipeMessage(Program.LocalPipeName, Environment.MachineName, "Forward Remote Button", Encoding.ASCII.GetBytes(button)); + PipeAccess.SendMessage(Common.ServerPipeName, Program.ServerHost, message.ToString()); + } + } + + Thread.Sleep(500); + } + else + { + IrssLog.Warn("Failed to register with server host \"{0}\", custom message(s) not sent", Program.ServerHost); + } + + StopComms(); + } + + } + else // GUI Start ... + { + if (String.IsNullOrEmpty(_serverHost)) + { + IrssUtils.Forms.ServerAddress serverAddress = new IrssUtils.Forms.ServerAddress(Environment.MachineName); + serverAddress.ShowDialog(); + + _serverHost = serverAddress.ServerHost; + } + + if (StartComms()) + { + Application.Run(new MainForm()); + + StopComms(); + } + + SaveSettings(); + } + + IrssLog.Close(); } + + static void LoadSettings() + { + try + { + _installFolder = SystemRegistry.GetInstallFolder(); + if (String.IsNullOrEmpty(_installFolder)) + _installFolder = "."; + else + _installFolder += "\\Virtual Remote"; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + + _installFolder = "."; + } + + try + { + XmlDocument doc = new XmlDocument(); + doc.Load(ConfigurationFile); + + _serverHost = doc.DocumentElement.Attributes["ServerHost"].Value; + _remoteSkin = doc.DocumentElement.Attributes["RemoteSkin"].Value; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + + _serverHost = String.Empty; + _remoteSkin = DefaultSkin; + } + } + static void SaveSettings() + { + try + { + XmlTextWriter writer = new XmlTextWriter(ConfigurationFile, System.Text.Encoding.UTF8); + writer.Formatting = Formatting.Indented; + writer.Indentation = 1; + writer.IndentChar = (char)9; + writer.WriteStartDocument(true); + writer.WriteStartElement("settings"); // <settings> + + writer.WriteAttributeString("ServerHost", _serverHost); + writer.WriteAttributeString("RemoteSkin", _remoteSkin); + + writer.WriteEndElement(); // </settings> + writer.WriteEndDocument(); + writer.Close(); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + + internal static bool StartComms() + { + try + { + if (OpenLocalPipe()) + { + _keepAliveThread = new Thread(new ThreadStart(KeepAliveThread)); + _keepAliveThread.Start(); + return true; + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + + return false; + } + internal static void StopComms() + { + _keepAlive = false; + + try + { + if (_keepAliveThread != null && _keepAliveThread.IsAlive) + _keepAliveThread.Abort(); + } + catch { } + + try + { + if (_registered) + { + _registered = false; + + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Unregister", null); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + } + } + catch { } + + try + { + if (PipeAccess.ServerRunning) + PipeAccess.StopServer(); + } + catch { } + } + + static bool OpenLocalPipe() + { + try + { + int pipeNumber = 1; + bool retry = false; + + do + { + string localPipeTest = String.Format(Common.LocalPipeFormat, pipeNumber); + + if (PipeAccess.PipeExists(String.Format("\\\\.\\pipe\\{0}", localPipeTest))) + { + if (++pipeNumber <= Common.MaximumLocalClientCount) + retry = true; + else + throw new Exception(String.Format("Maximum local client limit ({0}) reached", Common.MaximumLocalClientCount)); + } + else + { + if (!PipeAccess.StartServer(localPipeTest, new PipeMessageHandler(ReceivedMessage))) + throw new Exception(String.Format("Failed to start local pipe server \"{0}\"", localPipeTest)); + + _localPipeName = localPipeTest; + retry = false; + } + } + while (retry); + + return true; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + + static bool ConnectToServer() + { + try + { + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Register", null); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + return true; + } + catch (AppModule.NamedPipes.NamedPipeIOException) + { + return false; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + + static void KeepAliveThread() + { + Random random = new Random((int)DateTime.Now.Ticks); + bool reconnect; + int attempt; + + _registered = false; + _keepAlive = true; + while (_keepAlive) + { + reconnect = true; + + #region Connect to server + + IrssLog.Info("Connecting ({0}) ...", _serverHost); + attempt = 0; + while (_keepAlive && reconnect) + { + if (ConnectToServer()) + { + reconnect = false; + } + else + { + int wait; + + if (attempt <= 50) + attempt++; + + if (attempt > 50) + wait = 30; // 30 seconds + else if (attempt > 20) + wait = 10; // 10 seconds + else if (attempt > 10) + wait = 5; // 5 seconds + else + wait = 1; // 1 second + + for (int sleeps = 0; sleeps < wait && _keepAlive; sleeps++) + Thread.Sleep(1000); + } + } + + #endregion Connect to server + + #region Wait for registered + + // Give up after 10 seconds ... + attempt = 0; + while (_keepAlive && !_registered && !reconnect) + { + if (++attempt >= 10) + reconnect = true; + else + Thread.Sleep(1000); + } + + #endregion Wait for registered + + #region Registered ... + + if (_keepAlive && _registered && !reconnect) + IrssLog.Info("Connected ({0})", _serverHost); + + #endregion Registered ... + + #region Ping the server repeatedly + + while (_keepAlive && _registered && !reconnect) + { + int pingID = random.Next(); + long pingTime = DateTime.Now.Ticks; + + try + { + PipeMessage message = new PipeMessage(_localPipeName, Environment.MachineName, "Ping", BitConverter.GetBytes(pingID)); + PipeAccess.SendMessage(Common.ServerPipeName, _serverHost, message.ToString()); + } + catch + { + // Failed to ping ... reconnect ... + IrssLog.Warn("Failed to ping, attempting to reconnect ..."); + _registered = false; + reconnect = true; + break; + } + + // Wait 10 seconds for a ping echo ... + bool receivedEcho = false; + while (_keepAlive && _registered && !reconnect && + !receivedEcho && DateTime.Now.Ticks - pingTime < 10 * 1000 * 10000) + { + if (_echoID == pingID) + { + receivedEcho = true; + } + else + { + Thread.Sleep(1000); + } + } + + if (receivedEcho) // Received ping echo ... + { + // Wait 60 seconds before re-pinging ... + for (int sleeps = 0; sleeps < 60 && _keepAlive && _registered; sleeps++) + Thread.Sleep(1000); + } + else // Didn't receive ping echo ... + { + IrssLog.Warn("No echo to ping, attempting to reconnect ..."); + + // Break out of pinging cycle ... + _registered = false; + reconnect = true; + } + } + + #endregion Ping the server repeatedly + + } + + } + + static void ReceivedMessage(string message) + { + PipeMessage received = PipeMessage.FromString(message); + + IrssLog.Debug("Received Message \"{0}\"", received.Name); + + try + { + switch (received.Name) + { + case "Remote Button": + break; + + case "Register Success": + { + IrssLog.Info("Registered to IR Server"); + _registered = true; + //_transceiverInfo = TransceiverInfo.FromBytes(received.Data); + break; + } + + case "Register Failure": + { + IrssLog.Warn("IR Server refused to register"); + _registered = false; + break; + } + + case "Server Shutdown": + { + IrssLog.Warn("IR Server Shutdown - Tray Launcher disabled until IR Server returns"); + _registered = false; + break; + } + + case "Echo": + { + _echoID = BitConverter.ToInt32(received.Data, 0); + break; + } + + case "Error": + { + IrssLog.Error(Encoding.ASCII.GetString(received.Data)); + break; + } + + default: + { + IrssLog.Warn("Unknown message received from server: " + received.Name); + break; + } + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + } } Added: trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.Designer.cs =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.Designer.cs (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.Designer.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -0,0 +1,125 @@ +namespace CustomHIDReceiver +{ + partial class AdvancedSettings + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.numericUpDownInputByte = new System.Windows.Forms.NumericUpDown(); + this.labelInputByte = new System.Windows.Forms.Label(); + this.checkBoxUseAllBytes = new System.Windows.Forms.CheckBox(); + this.labelInputByteMask = new System.Windows.Forms.Label(); + this.numericUpDownInputByteMask = new System.Windows.Forms.NumericUpDown(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInputByte)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInputByteMask)).BeginInit(); + this.SuspendLayout(); + // + // numericUpDownInputByte + // + this.numericUpDownInputByte.Location = new System.Drawing.Point(112, 8); + this.numericUpDownInputByte.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.numericUpDownInputByte.Name = "numericUpDownInputByte"; + this.numericUpDownInputByte.Size = new System.Drawing.Size(56, 20); + this.numericUpDownInputByte.TabIndex = 0; + this.numericUpDownInputByte.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // labelInputByte + // + this.labelInputByte.Location = new System.Drawing.Point(8, 8); + this.labelInputByte.Name = "labelInputByte"; + this.labelInputByte.Size = new System.Drawing.Size(104, 20); + this.labelInputByte.TabIndex = 1; + this.labelInputByte.Text = "Input byte:"; + this.labelInputByte.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // checkBoxUseAllBytes + // + this.checkBoxUseAllBytes.AutoSize = true; + this.checkBoxUseAllBytes.Location = new System.Drawing.Point(8, 72); + this.checkBoxUseAllBytes.Name = "checkBoxUseAllBytes"; + this.checkBoxUseAllBytes.Size = new System.Drawing.Size(112, 17); + this.checkBoxUseAllBytes.TabIndex = 2; + this.checkBoxUseAllBytes.Text = "Use all input bytes"; + this.checkBoxUseAllBytes.UseVisualStyleBackColor = true; + // + // labelInputByteMask + // + this.labelInputByteMask.Location = new System.Drawing.Point(8, 40); + this.labelInputByteMask.Name = "labelInputByteMask"; + this.labelInputByteMask.Size = new System.Drawing.Size(104, 20); + this.labelInputByteMask.TabIndex = 4; + this.labelInputByteMask.Text = "Input byte mask:"; + this.labelInputByteMask.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // numericUpDownInputByteMask + // + this.numericUpDownInputByteMask.Location = new System.Drawing.Point(112, 40); + this.numericUpDownInputByteMask.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.numericUpDownInputByteMask.Name = "numericUpDownInputByteMask"; + this.numericUpDownInputByteMask.Size = new System.Drawing.Size(56, 20); + this.numericUpDownInputByteMask.TabIndex = 3; + this.numericUpDownInputByteMask.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // AdvancedSettings + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(176, 97); + this.Controls.Add(this.labelInputByteMask); + this.Controls.Add(this.numericUpDownInputByteMask); + this.Controls.Add(this.checkBoxUseAllBytes); + this.Controls.Add(this.labelInputByte); + this.Controls.Add(this.numericUpDownInputByte); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AdvancedSettings"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Advanced Settings"; + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInputByte)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownInputByteMask)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.NumericUpDown numericUpDownInputByte; + private System.Windows.Forms.Label labelInputByte; + private System.Windows.Forms.CheckBox checkBoxUseAllBytes; + private System.Windows.Forms.Label labelInputByteMask; + private System.Windows.Forms.NumericUpDown numericUpDownInputByteMask; + } +} \ No newline at end of file Added: trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.cs =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.cs (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace CustomHIDReceiver +{ + public partial class AdvancedSettings : Form + { + public AdvancedSettings() + { + InitializeComponent(); + } + } +} \ No newline at end of file Added: trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.resx =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.resx (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/AdvancedSettings.resx 2007-07-05 04:48:31 UTC (rev 671) @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root> \ No newline at end of file Added: trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.cs =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.cs (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.cs 2007-07-05 04:48:31 UTC (rev 671) @@ -0,0 +1,340 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.Xml; + +using Microsoft.Win32.SafeHandles; + +using IRServerPluginInterface; + +namespace CustomHIDReceiver +{ + + public class CustomHIDReceiver: IIRServerPlugin, IDisposable + { + + #region Constants + + public static readonly string ConfigurationFile = + Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + + "\\IR Server Suite\\IR Server\\Custom HID Receiver.xml"; + + static readonly string[] Ports = new string[] { "None" }; + static readonly string[] Speeds = new string[] { "None" }; + + const int DeviceBufferSize = 255; + + #endregion Constants + + #region Variables + + RemoteButtonHandler _remoteButtonHandler = null; + FileStream _deviceStream; + byte[] _deviceBuffer; + + string _deviceID; + int _inputByte; + byte _byteMask; + bool _useAllBytes; + + + + bool _disposed = false; + + #endregion Variables + + #region Constructor / Deconstructor + + public CustomHIDReceiver() + { + LoadSettings(); + } + + ~CustomHIDReceiver() + { + // call Dispose with false. Since we're in the + // destructor call, the managed resources will be + // disposed of anyways. + Dispose(false); + } + + #endregion Constructor / Deconstructor + + #region IDisposable Members + + public void Dispose() + { + // dispose of the managed and unmanaged resources + Dispose(true); + + // tell the GC that the Finalize process no longer needs + // to be run for this object. + GC.SuppressFinalize(this); + } + + #endregion + + #region IIRServerPlugin Members + + public string Name { get { return "Custom HID Receiver"; } } + public string Version { get { return "1.0.3.2"; } } + public string Author { get { return "and-81"; } } + public string Description { get { return "Supports HID USB devices."; } } + public bool CanReceive { get { return true; } } + public bool CanTransmit { get { return false; } } + public bool CanLearn { get { return false; } } + public bool CanConfigure { get { return true; } } + + public RemoteButtonHandler RemoteButtonCallback + { + get { return _remoteButtonHandler; } + set { _remoteButtonHandler = value; } + } + + public string[] AvailablePorts { get { return Ports; } } + public string[] AvailableSpeeds { get { return Speeds; } } + + public void Configure() + { + DeviceSelect deviceSelect = new DeviceSelect(_deviceID); + if (deviceSelect.ShowDialog() == DialogResult.OK) + { + _deviceID = deviceSelect.DeviceID; + SaveSettings(); + } + } + + public bool Start() + { + if (String.IsNullOrEmpty(_deviceID)) + throw new Exception("No HID Device selected for use"); + + Guid guid = new Guid(); + NativeMethods.HidD_GetHidGuid(ref guid); + + string devicePath = FindDevice(guid, _deviceID); + if (devicePath == null) + return false; + + SafeFileHandle deviceHandle = NativeMethods.CreateFile(devicePath, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, NativeMethods.EFileAttributes.Overlapped, IntPtr.Zero); + + if (deviceHandle.IsInvalid) + throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open USB HID Device"); + + //_deviceWatcher.RegisterDeviceRemoval(deviceHandle); + + _deviceBuffer = new byte[DeviceBufferSize]; + + _deviceStream = new FileStream(deviceHandle, FileAccess.Read, _deviceBuffer.Length, true); + _deviceStream.BeginRead(_deviceBuffer, 0, _deviceBuffer.Length, new AsyncCallback(OnReadComplete), null); + + return true; + } + public void Suspend() { } + public void Resume() { } + public void Stop() + { + if (_deviceStream == null) + return; + + try + { + _deviceStream.Close(); + } + catch (IOException) + { } + finally + { + _deviceStream = null; + } + } + + public bool Transmit(string file) { return false; } + public LearnStatus Learn(string file) { return LearnStatus.Failure; } + + public bool SetPort(string port) { return true; } + public bool SetSpeed(string speed) { return true; } + + #endregion IIRServerPlugin Members + + #region Implementation + + protected virtual void Dispose(bool disposeManagedResources) + { + // process only if mananged and unmanaged resources have + // not been disposed of. + if (!this._disposed) + { + if (disposeManagedResources) + { + // dispose managed resources + if (_deviceStream != null) + { + _deviceStream.Dispose(); + _deviceStream = null; + } + } + + // dispose unmanaged resources + this._disposed = true; + } + } + + void LoadSettings() + { + try + { + XmlDocument doc = new XmlDocument(); + doc.Load(ConfigurationFile); + + _deviceID = doc.DocumentElement.Attributes["DeviceID"].Value; + _inputByte = int.Parse(doc.DocumentElement.Attributes["InputByte"].Value); + _byteMask = byte.Parse(doc.DocumentElement.Attributes["ByteMask"].Value); + _useAllBytes = bool.Parse(doc.DocumentElement.Attributes["UseAllBytes"].Value); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + + _deviceID = String.Empty; + _inputByte = 3; + _byteMask = 0x7F; + _useAllBytes = false; + } + } + void SaveSettings() + { + try + { + XmlTextWriter writer = new XmlTextWriter(ConfigurationFile, System.Text.Encoding.UTF8); + writer.Formatting = Formatting.Indented; + writer.Indentation = 1; + writer.IndentChar = (char)9; + writer.WriteStartDocument(true); + writer.WriteStartElement("settings"); // <settings> + + writer.WriteAttributeString("DeviceID", _deviceID); + writer.WriteAttributeString("InputByte", _inputByte.ToString()); + writer.WriteAttributeString("ByteMask", _byteMask.ToString()); + writer.WriteAttributeString("UseAllBytes", _useAllBytes.ToString()); + + writer.WriteEndElement(); // </settings> + writer.WriteEndDocument(); + writer.Close(); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + } + + static string FindDevice(Guid classGuid, string deviceID) + { + int lastError; + + // 0x12 = DIGCF_PRESENT | DIGCF_DEVICEINTERFACE + IntPtr handle = NativeMethods.SetupDiGetClassDevs(ref classGuid, "", IntPtr.Zero, 0x12); + lastError = Marshal.GetLastWin32Error(); + + if (handle.ToInt32() == -1) + throw new Win32Exception(lastError); + + string devicePath = null; + + for (int deviceIndex = 0; ; deviceIndex++) + { + NativeMethods.DeviceInfoData deviceInfoData = new NativeMethods.DeviceInfoData(); + deviceInfoData.Size = Marshal.SizeOf(deviceInfoData); + + if (NativeMethods.SetupDiEnumDeviceInfo(handle, deviceIndex, ref deviceInfoData) == false) + { + // out of devices or do we have an error? + lastError = Marshal.GetLastWin32Error(); + if (lastError != 0x0103 && lastError != 0x007E) + { + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + break; + } + + NativeMethods.DeviceInterfaceData deviceInterfaceData = new NativeMethods.DeviceInterfaceData(); + deviceInterfaceData.Size = Marshal.SizeOf(deviceInterfaceData); + + if (NativeMethods.SetupDiEnumDeviceInterfaces(handle, ref deviceInfoData, ref classGuid, 0, ref deviceInterfaceData) == false) + { + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + uint cbData = 0; + + if (NativeMethods.SetupDiGetDeviceInterfaceDetail(handle, ref deviceInterfaceData, IntPtr.Zero, 0, ref cbData, IntPtr.Zero) == false && cbData == 0) + { + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + NativeMethods.DeviceInterfaceDetailData deviceInterfaceDetailData = new NativeMethods.DeviceInterfaceDetailData(); + deviceInterfaceDetailData.Size = 5; + + if (NativeMethods.SetupDiGetDeviceInterfaceDetail(handle, ref deviceInterfaceData, ref deviceInterfaceDetailData, cbData, IntPtr.Zero, IntPtr.Zero) == false) + { + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + if (deviceInterfaceDetailData.DevicePath.IndexOf(deviceID) != -1) + { + NativeMethods.SetupDiDestroyDeviceInfoList(handle); + devicePath = deviceInterfaceDetailData.DevicePath; + break; + } + } + + return devicePath; + } + + void OnReadComplete(IAsyncResult asyncResult) + { + try + { + int bytesRead = _deviceStream.EndRead(asyncResult); + + if (bytesRead == 0) + throw new Exception("Error reading from HID Device, zero bytes read"); + + if (_remoteButtonHandler != null) + { + if (_useAllBytes) + { + _remoteButtonHandler(BitConverter.ToString(_deviceBuffer, 0, bytesRead)); + } + else if (bytesRead > _inputByte) + { + int keyByte = _deviceBuffer[_inputByte] & _byteMask; + + string keyCode = keyByte.ToString("X2"); + + _remoteButtonHandler(keyCode); + } + } + + _deviceStream.BeginRead(_deviceBuffer, 0, _deviceBuffer.Length, new AsyncCallback(OnReadComplete), null); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + } + + #endregion Implementation + + } + +} Added: trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.csproj =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.csproj (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/Custom HID Receiver/Custom HID Receiver.csproj 2007-07-05 04:48:31 UTC (rev 671) @@ -0,0 +1,88 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{0F6576B4-C88E-4E79-B7E9-9480498C5A32}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>CustomHIDReceiver</RootNamespace> + <AssemblyName>Custom HID Receiver</AssemblyName> + <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>false</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>b... [truncated message content] |