Hardware/Heatmaster/HeatmasterGroup.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 256 6dc6410489f4
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2010 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Globalization;
    14 using System.IO.Ports;
    15 using System.Security;
    16 using System.Text;
    17 using System.Threading;
    18 using Microsoft.Win32;
    19 
    20 namespace OpenHardwareMonitor.Hardware.Heatmaster {
    21   internal class HeatmasterGroup : IGroup {
    22 
    23     private readonly List<Heatmaster> hardware = new List<Heatmaster>();
    24     private readonly StringBuilder report = new StringBuilder();
    25 
    26     private static string ReadLine(SerialPort port, int timeout) {
    27       int i = 0;
    28       StringBuilder builder = new StringBuilder();
    29       while (i < timeout) {
    30         while (port.BytesToRead > 0) {
    31           byte b = (byte)port.ReadByte();
    32           switch (b) {
    33             case 0xAA: return ((char)b).ToString();
    34             case 0x0D: return builder.ToString();
    35             default: builder.Append((char)b); break;
    36           }
    37         }
    38         i++;
    39         Thread.Sleep(1);
    40       }
    41       throw new TimeoutException();
    42     }
    43 
    44     private static string[] GetRegistryPortNames() {
    45       List<string> result = new List<string>();
    46       string[] paths = { "", "&MI_00" };
    47       try {
    48         foreach (string path in paths) {
    49           RegistryKey key = Registry.LocalMachine.OpenSubKey(
    50             @"SYSTEM\CurrentControlSet\Enum\USB\VID_10C4&PID_EA60" + path);
    51           if (key != null) {
    52             foreach (string subKeyName in key.GetSubKeyNames()) {
    53               RegistryKey subKey =
    54                 key.OpenSubKey(subKeyName + "\\" + "Device Parameters");
    55               if (subKey != null) {
    56                 string name = subKey.GetValue("PortName") as string;
    57                 if (name != null && !result.Contains(name))
    58                   result.Add(name);
    59               }
    60             }
    61           }
    62         }
    63       } catch (SecurityException) { }
    64       return result.ToArray();
    65     }
    66 
    67     public HeatmasterGroup(ISettings settings) {
    68       
    69       // No implementation for Heatmaster on Unix systems
    70       int p = (int)Environment.OSVersion.Platform;
    71       if ((p == 4) || (p == 128))
    72         return;
    73 
    74       string[] portNames = GetRegistryPortNames();      
    75       for (int i = 0; i < portNames.Length; i++) {
    76         bool isValid = false;
    77         try {        
    78           using (SerialPort serialPort =
    79             new SerialPort(portNames[i], 38400, Parity.None, 8, StopBits.One)) {
    80             serialPort.NewLine = ((char)0x0D).ToString();            
    81             report.Append("Port Name: "); report.AppendLine(portNames[i]);
    82 
    83             try {
    84               serialPort.Open();
    85             } catch (UnauthorizedAccessException) {
    86               report.AppendLine("Exception: Access Denied");
    87             }
    88 
    89             if (serialPort.IsOpen) {
    90               serialPort.DiscardInBuffer();
    91               serialPort.DiscardOutBuffer();
    92               serialPort.Write(new byte[] { 0xAA }, 0, 1);
    93 
    94               int j = 0;
    95               while (serialPort.BytesToRead == 0 && j < 10) {
    96                 Thread.Sleep(20);
    97                 j++;
    98               }
    99               if (serialPort.BytesToRead > 0) {
   100                 bool flag = false;
   101                 while (serialPort.BytesToRead > 0 && !flag) {
   102                   flag |= (serialPort.ReadByte() == 0xAA);
   103                 }
   104                 if (flag) {
   105                   serialPort.WriteLine("[0:0]RH");
   106                   try {
   107                     int k = 0;
   108                     int revision = 0;
   109                     while (k < 5) {
   110                       string line = ReadLine(serialPort, 100);
   111                       if (line.StartsWith("-[0:0]RH:",
   112                         StringComparison.Ordinal)) {
   113                         revision = int.Parse(line.Substring(9), 
   114                           CultureInfo.InvariantCulture);
   115                         break;
   116                       }
   117                       k++;
   118                     }
   119                     isValid = (revision == 770);
   120                     if (!isValid) {
   121                       report.Append("Status: Wrong Hardware Revision " +
   122                         revision.ToString(CultureInfo.InvariantCulture));
   123                     }
   124                   } catch (TimeoutException) {
   125                     report.AppendLine("Status: Timeout Reading Revision");
   126                   }
   127                 } else {
   128                   report.AppendLine("Status: Wrong Startflag");
   129                 }
   130               } else {
   131                 report.AppendLine("Status: No Response");
   132               }
   133               serialPort.DiscardInBuffer();
   134             } else {
   135               report.AppendLine("Status: Port not Open");
   136             }            
   137           }
   138         } catch (Exception e) {
   139           report.AppendLine(e.ToString());
   140         }
   141 
   142         if (isValid) {
   143           report.AppendLine("Status: OK");
   144           hardware.Add(new Heatmaster(portNames[i], settings));
   145         }
   146         report.AppendLine();
   147       }
   148     }
   149 
   150     public IHardware[] Hardware {
   151       get {
   152         return hardware.ToArray();
   153       }
   154     }
   155 
   156     public string GetReport() {
   157       if (report.Length > 0) {
   158         StringBuilder r = new StringBuilder();
   159         r.AppendLine("Serial Port Heatmaster");
   160         r.AppendLine();
   161         r.Append(report);
   162         r.AppendLine();
   163         return r.ToString();
   164       } else
   165         return null;
   166     }
   167 
   168     public void Close() {
   169       foreach (Heatmaster heatmaster in hardware)
   170         heatmaster.Close();
   171     }
   172   }
   173 }