Hardware/ATI/ADL.cs
author moel.mich
Wed, 27 Jan 2010 18:12:51 +0000
changeset 2 105939e4eb7e
child 3 1a0928afac6b
permissions -rw-r--r--
Fixed a NullReferenceException in the HDD SMART code.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Runtime.InteropServices;
    41 
    42 namespace OpenHardwareMonitor.Hardware.ATI {
    43   
    44   [StructLayout(LayoutKind.Sequential)]
    45   public struct ADLAdapterInfo {
    46     public int Size;
    47     public int AdapterIndex;
    48     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    49     public string UDID;
    50     public int BusNumber;
    51     public int DriverNumber;
    52     public int FunctionNumber;
    53     public int VendorID;
    54     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    55     public string AdapterName;
    56     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    57     public string DisplayName;
    58     public int Present;
    59     public int Exist;
    60     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    61     public string DriverPath;
    62     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    63     public string DriverPathExt;
    64     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    65     public string PNPString;
    66     public int OSDisplayIndex;
    67   }
    68 
    69   [StructLayout(LayoutKind.Sequential)]
    70   public struct ADLPMActivity {
    71     public int Size;
    72     public int EngineClock;
    73     public int MemoryClock;
    74     public int Vddc;
    75     public int ActivityPercent;
    76     public int CurrentPerformanceLevel;
    77     public int CurrentBusSpeed;
    78     public int CurrentBusLanes;
    79     public int MaximumBusLanes;
    80     public int Reserved;
    81   }
    82 
    83   [StructLayout(LayoutKind.Sequential)]
    84   public struct ADLTemperature {
    85     public int Size;
    86     public int Temperature;
    87   }
    88 
    89   [StructLayout(LayoutKind.Sequential)]
    90   public struct ADLFanSpeedValue {
    91     public int Size;
    92     public int SpeedType;
    93     public int FanSpeed;
    94     public int Flags;
    95   }
    96 
    97   [StructLayout(LayoutKind.Sequential)]
    98   public struct ADLFanSpeedInfo {
    99     public int Size;
   100     public int Flags;
   101     public int MinPercent;
   102     public int MaxPercent;
   103     public int MinRPM;
   104     public int MaxRPM;
   105   }
   106 
   107   public class ADL {
   108     public const int ADL_MAX_PATH = 256;
   109     public const int ADL_MAX_ADAPTERS = 40;
   110     public const int ADL_MAX_DISPLAYS = 40;
   111     public const int ADL_MAX_DEVICENAME = 32;
   112     public const int ADL_SUCCESS = 0;
   113     public const int ADL_FAIL = -1;
   114     public const int ADL_DRIVER_OK = 0;
   115     public const int ADL_MAX_GLSYNC_PORTS = 8;
   116     public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
   117     public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
   118 
   119     public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
   120     public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
   121 
   122     public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
   123     public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
   124     public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
   125     public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
   126 
   127     private delegate int ADL_Main_Control_CreateDelegate(
   128       ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
   129     private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
   130       int size);
   131 
   132     public delegate int ADL_Main_Control_DestroyDelegate();
   133     public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
   134       ref int numAdapters);    
   135     public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
   136       out int adapterID);
   137     public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
   138       out int status);
   139     public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
   140       int iAdapterIndex, ref ADLPMActivity activity);
   141     public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
   142         int thermalControllerIndex, ref ADLTemperature temperature);
   143     public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
   144         int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
   145     public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
   146       int adapterIndex, int thermalControllerIndex,
   147       ref ADLFanSpeedInfo fanSpeedInfo);
   148 
   149     private static ADL_Main_Control_CreateDelegate
   150       _ADL_Main_Control_Create;
   151     private static ADL_Adapter_AdapterInfo_GetDelegate
   152       _ADL_Adapter_AdapterInfo_Get;
   153 
   154     public static ADL_Main_Control_DestroyDelegate
   155       ADL_Main_Control_Destroy;
   156     public static ADL_Adapter_NumberOfAdapters_GetDelegate
   157       ADL_Adapter_NumberOfAdapters_Get;
   158     public static ADL_Adapter_ID_GetDelegate
   159       ADL_Adapter_ID_Get;
   160     public static ADL_Adapter_Active_GetDelegate
   161       ADL_Adapter_Active_Get;
   162     public static ADL_Overdrive5_CurrentActivity_GetDelegate
   163       ADL_Overdrive5_CurrentActivity_Get;
   164     public static ADL_Overdrive5_Temperature_GetDelegate
   165       ADL_Overdrive5_Temperature_Get;
   166     public static ADL_Overdrive5_FanSpeed_GetDelegate
   167       ADL_Overdrive5_FanSpeed_Get;
   168     public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
   169       ADL_Overdrive5_FanSpeedInfo_Get;
   170 
   171     private static string GetDllName() {
   172       int p = (int)System.Environment.OSVersion.Platform;
   173       if ((p == 4) || (p == 128)) {
   174         if (IntPtr.Size == 4) {
   175           return "atiadlxy.so";
   176         } else {
   177           return "atiadlxx.so";
   178         }
   179       } else {
   180         if (IntPtr.Size == 4) {
   181           return "atiadlxy.dll";
   182         } else {
   183           return "atiadlxx.dll";
   184         }
   185       }
   186     }
   187 
   188     private static void GetDelegate<T>(string entryPoint, out T newDelegate)
   189       where T : class 
   190     {
   191       DllImportAttribute attribute = new DllImportAttribute(GetDllName());
   192       attribute.CallingConvention = CallingConvention.StdCall;
   193       attribute.PreserveSig = true;
   194       attribute.EntryPoint = entryPoint;
   195       PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
   196     }
   197 
   198     static ADL() {
   199        GetDelegate("ADL_Main_Control_Create", 
   200          out _ADL_Main_Control_Create);
   201        GetDelegate("ADL_Adapter_AdapterInfo_Get", 
   202          out _ADL_Adapter_AdapterInfo_Get);
   203        GetDelegate("ADL_Main_Control_Destroy", 
   204          out ADL_Main_Control_Destroy);
   205        GetDelegate("ADL_Adapter_NumberOfAdapters_Get", 
   206          out ADL_Adapter_NumberOfAdapters_Get);
   207        GetDelegate("ADL_Adapter_ID_Get", 
   208          out ADL_Adapter_ID_Get);
   209        GetDelegate("ADL_Adapter_Active_Get", 
   210          out ADL_Adapter_Active_Get);
   211        GetDelegate("ADL_Overdrive5_CurrentActivity_Get", 
   212          out ADL_Overdrive5_CurrentActivity_Get);
   213        GetDelegate("ADL_Overdrive5_Temperature_Get", 
   214          out ADL_Overdrive5_Temperature_Get);
   215        GetDelegate("ADL_Overdrive5_FanSpeed_Get", 
   216          out ADL_Overdrive5_FanSpeed_Get);
   217        GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
   218           out ADL_Overdrive5_FanSpeedInfo_Get);
   219     }
   220 
   221     private ADL() { }
   222 
   223     public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
   224       return _ADL_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters);
   225     }
   226 
   227     public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
   228       int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
   229       int size = info.Length * elementSize;
   230       IntPtr ptr = Marshal.AllocHGlobal(size);
   231       int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
   232       for (int i = 0; i < info.Length; i++)
   233         info[i] = (ADLAdapterInfo)
   234           Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
   235           typeof(ADLAdapterInfo));
   236       Marshal.FreeHGlobal(ptr);
   237       return result;
   238     }
   239 
   240     private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
   241 
   242     private static IntPtr Main_Memory_Alloc(int size) {
   243       return Marshal.AllocHGlobal(size);;
   244     }
   245 
   246     private static void Main_Memory_Free(IntPtr buffer) {
   247       if (IntPtr.Zero != buffer)
   248         Marshal.FreeHGlobal(buffer);
   249     }
   250   }
   251 }