Fixed Issue 213.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
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
9 http://www.mozilla.org/MPL/
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.
15 The Original Code is the Open Hardware Monitor code.
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-2012
20 the Initial Developer. All Rights Reserved.
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.
39 using System.Runtime.InteropServices;
40 using System.Text.RegularExpressions;
42 namespace OpenHardwareMonitor.Hardware.ATI {
44 [StructLayout(LayoutKind.Sequential)]
45 internal struct ADLAdapterInfo {
47 public int AdapterIndex;
48 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
51 public int DeviceNumber;
52 public int FunctionNumber;
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;
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;
69 [StructLayout(LayoutKind.Sequential)]
70 internal struct ADLPMActivity {
72 public int EngineClock;
73 public int MemoryClock;
75 public int ActivityPercent;
76 public int CurrentPerformanceLevel;
77 public int CurrentBusSpeed;
78 public int CurrentBusLanes;
79 public int MaximumBusLanes;
83 [StructLayout(LayoutKind.Sequential)]
84 internal struct ADLTemperature {
86 public int Temperature;
89 [StructLayout(LayoutKind.Sequential)]
90 internal struct ADLFanSpeedValue {
97 [StructLayout(LayoutKind.Sequential)]
98 internal struct ADLFanSpeedInfo {
101 public int MinPercent;
102 public int MaxPercent;
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_OK = 0;
113 public const int ADL_ERR = -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;
119 public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
120 public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
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 public const int ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1;
128 public const int ATI_VENDOR_ID = 0x1002;
130 private delegate int ADL_Main_Control_CreateDelegate(
131 ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
132 private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
135 public delegate int ADL_Main_Control_DestroyDelegate();
136 public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
137 ref int numAdapters);
138 public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
140 public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
142 public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
144 public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
145 int iAdapterIndex, ref ADLPMActivity activity);
146 public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
147 int thermalControllerIndex, ref ADLTemperature temperature);
148 public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
149 int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue);
150 public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
151 int adapterIndex, int thermalControllerIndex,
152 ref ADLFanSpeedInfo fanSpeedInfo);
153 public delegate int ADL_Overdrive5_FanSpeedToDefault_SetDelegate(
154 int adapterIndex, int thermalControllerIndex);
155 public delegate int ADL_Overdrive5_FanSpeed_SetDelegate(int adapterIndex,
156 int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue);
158 private static ADL_Main_Control_CreateDelegate
159 _ADL_Main_Control_Create;
160 private static ADL_Adapter_AdapterInfo_GetDelegate
161 _ADL_Adapter_AdapterInfo_Get;
163 public static ADL_Main_Control_DestroyDelegate
164 ADL_Main_Control_Destroy;
165 public static ADL_Adapter_NumberOfAdapters_GetDelegate
166 ADL_Adapter_NumberOfAdapters_Get;
167 public static ADL_Adapter_ID_GetDelegate
169 public static ADL_Display_AdapterID_GetDelegate
170 _ADL_Display_AdapterID_Get;
171 public static ADL_Adapter_Active_GetDelegate
172 ADL_Adapter_Active_Get;
173 public static ADL_Overdrive5_CurrentActivity_GetDelegate
174 ADL_Overdrive5_CurrentActivity_Get;
175 public static ADL_Overdrive5_Temperature_GetDelegate
176 ADL_Overdrive5_Temperature_Get;
177 public static ADL_Overdrive5_FanSpeed_GetDelegate
178 ADL_Overdrive5_FanSpeed_Get;
179 public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
180 ADL_Overdrive5_FanSpeedInfo_Get;
181 public static ADL_Overdrive5_FanSpeedToDefault_SetDelegate
182 ADL_Overdrive5_FanSpeedToDefault_Set;
183 public static ADL_Overdrive5_FanSpeed_SetDelegate
184 ADL_Overdrive5_FanSpeed_Set;
186 private static string dllName;
188 private static void GetDelegate<T>(string entryPoint, out T newDelegate)
191 DllImportAttribute attribute = new DllImportAttribute(dllName);
192 attribute.CallingConvention = CallingConvention.StdCall;
193 attribute.PreserveSig = true;
194 attribute.EntryPoint = entryPoint;
195 PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
198 private static void CreateDelegates(string name) {
199 int p = (int)Environment.OSVersion.Platform;
200 if ((p == 4) || (p == 128))
201 dllName = name + ".so";
203 dllName = name + ".dll";
205 GetDelegate("ADL_Main_Control_Create",
206 out _ADL_Main_Control_Create);
207 GetDelegate("ADL_Adapter_AdapterInfo_Get",
208 out _ADL_Adapter_AdapterInfo_Get);
209 GetDelegate("ADL_Main_Control_Destroy",
210 out ADL_Main_Control_Destroy);
211 GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
212 out ADL_Adapter_NumberOfAdapters_Get);
213 GetDelegate("ADL_Adapter_ID_Get",
214 out _ADL_Adapter_ID_Get);
215 GetDelegate("ADL_Display_AdapterID_Get",
216 out _ADL_Display_AdapterID_Get);
217 GetDelegate("ADL_Adapter_Active_Get",
218 out ADL_Adapter_Active_Get);
219 GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
220 out ADL_Overdrive5_CurrentActivity_Get);
221 GetDelegate("ADL_Overdrive5_Temperature_Get",
222 out ADL_Overdrive5_Temperature_Get);
223 GetDelegate("ADL_Overdrive5_FanSpeed_Get",
224 out ADL_Overdrive5_FanSpeed_Get);
225 GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
226 out ADL_Overdrive5_FanSpeedInfo_Get);
227 GetDelegate("ADL_Overdrive5_FanSpeedToDefault_Set",
228 out ADL_Overdrive5_FanSpeedToDefault_Set);
229 GetDelegate("ADL_Overdrive5_FanSpeed_Set",
230 out ADL_Overdrive5_FanSpeed_Set);
234 CreateDelegates("atiadlxx");
239 public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
242 return _ADL_Main_Control_Create(Main_Memory_Alloc,
243 enumConnectedAdapters);
245 CreateDelegates("atiadlxy");
246 return _ADL_Main_Control_Create(Main_Memory_Alloc,
247 enumConnectedAdapters);
254 public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
255 int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
256 int size = info.Length * elementSize;
257 IntPtr ptr = Marshal.AllocHGlobal(size);
258 int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
259 for (int i = 0; i < info.Length; i++)
260 info[i] = (ADLAdapterInfo)
261 Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
262 typeof(ADLAdapterInfo));
263 Marshal.FreeHGlobal(ptr);
265 // the ADLAdapterInfo.VendorID field reported by ADL is wrong on
266 // Windows systems (parse error), so we fix this here
267 for (int i = 0; i < info.Length; i++) {
268 // try Windows UDID format
269 Match m = Regex.Match(info[i].UDID, "PCI_VEN_([A-Fa-f0-9]{1,4})&.*");
270 if (m.Success && m.Groups.Count == 2) {
271 info[i].VendorID = Convert.ToInt32(m.Groups[1].Value, 16);
274 // if above failed, try Unix UDID format
275 m = Regex.Match(info[i].UDID, "[0-9]+:[0-9]+:([0-9]+):[0-9]+:[0-9]+");
276 if (m.Success && m.Groups.Count == 2) {
277 info[i].VendorID = Convert.ToInt32(m.Groups[1].Value, 10);
284 public static int ADL_Adapter_ID_Get(int adapterIndex,
287 return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
288 } catch (EntryPointNotFoundException) {
290 return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
291 } catch (EntryPointNotFoundException) {
298 private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
300 // create a Main_Memory_Alloc delegate and keep it alive
301 private static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc =
303 return Marshal.AllocHGlobal(size);
306 private static void Main_Memory_Free(IntPtr buffer) {
307 if (IntPtr.Zero != buffer)
308 Marshal.FreeHGlobal(buffer);