Added more error checking to the T-Balancer enumeration code. This hopefully fixes an IndexOutOfRangeException in the TBalancerGroup constructor.
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-2010
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;
42 namespace OpenHardwareMonitor.Hardware.Nvidia {
44 internal enum NvStatus {
47 LIBRARY_NOT_FOUND = -2,
48 NO_IMPLEMENTATION = -3,
49 API_NOT_INTIALIZED = -4,
50 INVALID_ARGUMENT = -5,
51 NVIDIA_DEVICE_NOT_FOUND = -6,
54 INCOMPATIBLE_STRUCT_VERSION = -9,
55 HANDLE_INVALIDATED = -10,
56 OPENGL_CONTEXT_NOT_CURRENT = -11,
58 INSTRUMENTATION_DISABLED = -13,
59 EXPECTED_LOGICAL_GPU_HANDLE = -100,
60 EXPECTED_PHYSICAL_GPU_HANDLE = -101,
61 EXPECTED_DISPLAY_HANDLE = -102,
62 INVALID_COMBINATION = -103,
64 PORTID_NOT_FOUND = -105,
65 EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
66 INVALID_PERF_LEVEL = -107,
68 NV_PERSIST_FILE_NOT_FOUND = -109,
69 PERSIST_DATA_NOT_FOUND = -110,
70 EXPECTED_TV_DISPLAY = -111,
71 EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112,
72 NO_ACTIVE_SLI_TOPOLOGY = -113,
73 SLI_RENDERING_MODE_NOTALLOWED = -114,
74 EXPECTED_DIGITAL_FLAT_PANEL = -115,
75 ARGUMENT_EXCEED_MAX_SIZE = -116,
76 DEVICE_SWITCHING_NOT_ALLOWED = -117,
77 TESTING_CLOCKS_NOT_SUPPORTED = -118,
78 UNKNOWN_UNDERSCAN_CONFIG = -119,
79 TIMEOUT_RECONFIGURING_GPU_TOPO = -120,
80 DATA_NOT_FOUND = -121,
81 EXPECTED_ANALOG_DISPLAY = -122,
83 REQUIRES_REBOOT = -124,
84 INVALID_HYBRID_MODE = -125,
85 MIXED_TARGET_TYPES = -126,
86 SYSWOW64_NOT_SUPPORTED = -127,
87 IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128,
88 REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129,
90 WAS_STILL_DRAWING = -131,
91 FILE_NOT_FOUND = -132,
92 TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
94 D3D10_1_LIBRARY_NOT_FOUND = -135,
95 FUNCTION_NOT_FOUND = -136
98 internal enum NvThermalController {
114 internal enum NvThermalTarget {
124 [StructLayout(LayoutKind.Sequential, Pack = 8)]
125 internal struct NvSensor {
126 public NvThermalController Controller;
127 public uint DefaultMinTemp;
128 public uint DefaultMaxTemp;
129 public uint CurrentTemp;
130 public NvThermalTarget Target;
133 [StructLayout(LayoutKind.Sequential, Pack = 8)]
134 internal struct NvGPUThermalSettings {
137 [MarshalAs(UnmanagedType.ByValArray,
138 SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
139 public NvSensor[] Sensor;
142 [StructLayout(LayoutKind.Sequential)]
143 internal struct NvDisplayHandle {
144 private readonly IntPtr ptr;
147 [StructLayout(LayoutKind.Sequential)]
148 internal struct NvPhysicalGpuHandle {
149 private readonly IntPtr ptr;
152 [StructLayout(LayoutKind.Sequential, Pack = 8)]
153 internal struct NvClocks {
155 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_CLOCKS_PER_GPU)]
159 [StructLayout(LayoutKind.Sequential, Pack = 8)]
160 internal struct NvPState {
162 public int Percentage;
165 [StructLayout(LayoutKind.Sequential, Pack = 8)]
166 internal struct NvPStates {
169 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_PSTATES_PER_GPU)]
170 public NvPState[] PStates;
173 [StructLayout(LayoutKind.Sequential, Pack = 8)]
174 internal struct NvUsages {
176 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_USAGES_PER_GPU)]
180 [StructLayout(LayoutKind.Sequential, Pack = 8)]
181 internal struct NvCooler {
183 public int Controller;
184 public int DefaultMin;
185 public int DefaultMax;
186 public int CurrentMin;
187 public int CurrentMax;
188 public int CurrentLevel;
189 public int DefaultPolicy;
190 public int CurrentPolicy;
192 public int ControlType;
196 [StructLayout(LayoutKind.Sequential, Pack = 8)]
197 internal struct NvGPUCoolerSettings {
200 [MarshalAs(UnmanagedType.ByValArray, SizeConst = NVAPI.MAX_COOLER_PER_GPU)]
201 public NvCooler[] Cooler;
204 [StructLayout(LayoutKind.Sequential, Pack = 8)]
205 internal struct NvMemoryInfo {
207 [MarshalAs(UnmanagedType.ByValArray, SizeConst =
208 NVAPI.MAX_MEMORY_VALUES_PER_GPU)]
209 public uint[] Values;
212 [StructLayout(LayoutKind.Sequential, Pack = 8)]
213 internal struct NvDisplayDriverVersion {
215 public uint DriverVersion;
216 public uint BldChangeListNum;
217 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
218 public string BuildBranch;
219 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.SHORT_STRING_MAX)]
220 public string Adapter;
223 internal class NVAPI {
225 public const int MAX_PHYSICAL_GPUS = 64;
226 public const int SHORT_STRING_MAX = 64;
228 public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
229 public const int MAX_CLOCKS_PER_GPU = 0x120;
230 public const int MAX_PSTATES_PER_GPU = 8;
231 public const int MAX_USAGES_PER_GPU = 33;
232 public const int MAX_COOLER_PER_GPU = 20;
233 public const int MAX_MEMORY_VALUES_PER_GPU = 5;
235 public static readonly uint GPU_THERMAL_SETTINGS_VER = (uint)
236 Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
237 public static readonly uint GPU_CLOCKS_VER = (uint)
238 Marshal.SizeOf(typeof(NvClocks)) | 0x20000;
239 public static readonly uint GPU_PSTATES_VER = (uint)
240 Marshal.SizeOf(typeof(NvPStates)) | 0x10000;
241 public static readonly uint GPU_USAGES_VER = (uint)
242 Marshal.SizeOf(typeof(NvUsages)) | 0x10000;
243 public static readonly uint GPU_COOLER_SETTINGS_VER = (uint)
244 Marshal.SizeOf(typeof(NvGPUCoolerSettings)) | 0x20000;
245 public static readonly uint GPU_MEMORY_INFO_VER = (uint)
246 Marshal.SizeOf(typeof(NvMemoryInfo)) | 0x20000;
247 public static readonly uint DISPLAY_DRIVER_VERSION_VER = (uint)
248 Marshal.SizeOf(typeof(NvDisplayDriverVersion)) | 0x10000;
250 private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
251 private delegate NvStatus NvAPI_InitializeDelegate();
252 private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
253 NvPhysicalGpuHandle gpuHandle, StringBuilder name);
255 public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
256 NvPhysicalGpuHandle gpuHandle, int sensorIndex,
257 ref NvGPUThermalSettings nvGPUThermalSettings);
258 public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
259 ref NvDisplayHandle displayHandle);
260 public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
261 NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
263 public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
264 [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
265 public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
266 NvPhysicalGpuHandle gpuHandle, out int value);
267 public delegate NvStatus NvAPI_GPU_GetAllClocksDelegate(
268 NvPhysicalGpuHandle gpuHandle, ref NvClocks nvClocks);
269 public delegate NvStatus NvAPI_GPU_GetPStatesDelegate(
270 NvPhysicalGpuHandle gpuHandle, ref NvPStates nvPStates);
271 public delegate NvStatus NvAPI_GPU_GetUsagesDelegate(
272 NvPhysicalGpuHandle gpuHandle, ref NvUsages nvUsages);
273 public delegate NvStatus NvAPI_GPU_GetCoolerSettingsDelegate(
274 NvPhysicalGpuHandle gpuHandle, int coolerIndex,
275 ref NvGPUCoolerSettings nvGPUCoolerSettings);
276 public delegate NvStatus NvAPI_GPU_GetMemoryInfoDelegate(
277 NvDisplayHandle displayHandle, ref NvMemoryInfo nvMemoryInfo);
278 public delegate NvStatus NvAPI_GetDisplayDriverVersionDelegate(
279 NvDisplayHandle displayHandle, [In, Out] ref NvDisplayDriverVersion
280 nvDisplayDriverVersion);
281 public delegate NvStatus NvAPI_GetInterfaceVersionStringDelegate(
282 StringBuilder version);
284 private static readonly bool available;
285 private static readonly nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
286 private static readonly NvAPI_InitializeDelegate NvAPI_Initialize;
287 private static readonly NvAPI_GPU_GetFullNameDelegate
288 _NvAPI_GPU_GetFullName;
289 private static readonly NvAPI_GetInterfaceVersionStringDelegate
290 _NvAPI_GetInterfaceVersionString;
292 public static readonly NvAPI_GPU_GetThermalSettingsDelegate
293 NvAPI_GPU_GetThermalSettings;
294 public static readonly NvAPI_EnumNvidiaDisplayHandleDelegate
295 NvAPI_EnumNvidiaDisplayHandle;
296 public static readonly NvAPI_GetPhysicalGPUsFromDisplayDelegate
297 NvAPI_GetPhysicalGPUsFromDisplay;
298 public static readonly NvAPI_EnumPhysicalGPUsDelegate
299 NvAPI_EnumPhysicalGPUs;
300 public static readonly NvAPI_GPU_GetTachReadingDelegate
301 NvAPI_GPU_GetTachReading;
302 public static readonly NvAPI_GPU_GetAllClocksDelegate
303 NvAPI_GPU_GetAllClocks;
304 public static readonly NvAPI_GPU_GetPStatesDelegate
305 NvAPI_GPU_GetPStates;
306 public static readonly NvAPI_GPU_GetUsagesDelegate
308 public static readonly NvAPI_GPU_GetCoolerSettingsDelegate
309 NvAPI_GPU_GetCoolerSettings;
310 public static readonly NvAPI_GPU_GetMemoryInfoDelegate
311 NvAPI_GPU_GetMemoryInfo;
312 public static readonly NvAPI_GetDisplayDriverVersionDelegate
313 NvAPI_GetDisplayDriverVersion;
317 public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
319 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
321 if (_NvAPI_GPU_GetFullName != null)
322 status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
324 status = NvStatus.FUNCTION_NOT_FOUND;
325 name = builder.ToString();
329 public static NvStatus NvAPI_GetInterfaceVersionString(out string version) {
330 StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
332 if (_NvAPI_GetInterfaceVersionString != null)
333 status = _NvAPI_GetInterfaceVersionString(builder);
335 status = NvStatus.FUNCTION_NOT_FOUND;
336 version = builder.ToString();
340 private static string GetDllName() {
341 if (IntPtr.Size == 4) {
344 return "nvapi64.dll";
348 private static void GetDelegate<T>(uint id, out T newDelegate)
351 IntPtr ptr = nvapi_QueryInterface(id);
352 if (ptr != IntPtr.Zero) {
354 Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
361 DllImportAttribute attribute = new DllImportAttribute(GetDllName());
362 attribute.CallingConvention = CallingConvention.Cdecl;
363 attribute.PreserveSig = true;
364 attribute.EntryPoint = "nvapi_QueryInterface";
365 PInvokeDelegateFactory.CreateDelegate(attribute,
366 out nvapi_QueryInterface);
369 GetDelegate(0x0150E828, out NvAPI_Initialize);
370 } catch (DllNotFoundException) { return; }
371 catch (EntryPointNotFoundException) { return; }
372 catch (ArgumentNullException) { return; }
374 if (NvAPI_Initialize() == NvStatus.OK) {
375 GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
376 GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
377 GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
378 GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
379 GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
380 GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);
381 GetDelegate(0x1BD69F49, out NvAPI_GPU_GetAllClocks);
382 GetDelegate(0x60DED2ED, out NvAPI_GPU_GetPStates);
383 GetDelegate(0x189A1FDF, out NvAPI_GPU_GetUsages);
384 GetDelegate(0xDA141340, out NvAPI_GPU_GetCoolerSettings);
385 GetDelegate(0x774AA982, out NvAPI_GPU_GetMemoryInfo);
386 GetDelegate(0xF951A4D1, out NvAPI_GetDisplayDriverVersion);
387 GetDelegate(0x01053FA5, out _NvAPI_GetInterfaceVersionString);
393 public static bool IsAvailable {
394 get { return available; }