forked from Rem0o/FanControl.HWInfo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HwInfo.cs
172 lines (142 loc) · 6.25 KB
/
HwInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
namespace FanControl.HWInfo
{
public class HWInfo : IDisposable
{
private const string HWINFO_SHARED_MEM_FILE_NAME = "Global\\HWiNFO_SENS_SM2";
private const int HWINFO_SENSORS_STRING_LEN = 128;
private const int HWINFO_UNIT_STRING_LEN = 16;
private MemoryMappedFile _memoryMappedFile;
private MemoryMappedViewAccessor _accessor;
private _HWiNFO_SHARED_MEM _sharedMemory;
private readonly List<HWInfoSensorSource> _sensors = new List<HWInfoSensorSource>();
public HWInfo()
{
try
{
_memoryMappedFile = MemoryMappedFile.OpenExisting(HWINFO_SHARED_MEM_FILE_NAME, MemoryMappedFileRights.Read);
_accessor = _memoryMappedFile.CreateViewAccessor(0L, Marshal.SizeOf(typeof(_HWiNFO_SHARED_MEM)), MemoryMappedFileAccess.Read);
_sharedMemory = new _HWiNFO_SHARED_MEM();
_accessor.Read(0L, out _sharedMemory);
_sensors.AddRange(ReadSensorSources());
FillSensors();
}
catch (Exception exception)
{
Dispose();
throw exception;
}
}
public void Dispose()
{
_accessor?.Dispose();
_memoryMappedFile?.Dispose();
}
public IEnumerable<HWInfoSensorSource> SensorsSource => _sensors;
private IEnumerable<HWInfoSensorSource> ReadSensorSources()
{
for (uint index = 0; index < _sharedMemory.dwNumSensorElements; ++index)
{
using (MemoryMappedViewStream viewStream = _memoryMappedFile.CreateViewStream(_sharedMemory.dwOffsetOfSensorSection + index * _sharedMemory.dwSizeOfSensorElement, _sharedMemory.dwSizeOfSensorElement, MemoryMappedFileAccess.Read))
{
byte[] buffer = new byte[(int)_sharedMemory.dwSizeOfSensorElement];
viewStream.Read(buffer, 0, (int)_sharedMemory.dwSizeOfSensorElement);
GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
_HWiNFO_SENSOR structure = (_HWiNFO_SENSOR)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(_HWiNFO_SENSOR));
gcHandle.Free();
yield return new HWInfoSensorSource(structure);
}
}
}
private void FillSensors()
{
for (uint index = 0; index < _sharedMemory.dwNumReadingElements; ++index)
{
uint i = index;
_HWiNFO_ELEMENT element = GetHWInfoElement(i);
_sensors[(int)element.dwSensorIndex].Sensors.Add(new HWInfoSensor(() => GetHWInfoElement(i)));
}
}
private _HWiNFO_ELEMENT GetHWInfoElement(uint index)
{
_HWiNFO_ELEMENT structure;
using (MemoryMappedViewStream viewStream = _memoryMappedFile.CreateViewStream(_sharedMemory.dwOffsetOfReadingSection + index * _sharedMemory.dwSizeOfReadingElement, _sharedMemory.dwSizeOfReadingElement, MemoryMappedFileAccess.Read))
{
byte[] buffer = new byte[(int)_sharedMemory.dwSizeOfReadingElement];
viewStream.Read(buffer, 0, (int)_sharedMemory.dwSizeOfReadingElement);
GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
structure = (_HWiNFO_ELEMENT)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(_HWiNFO_ELEMENT));
gcHandle.Free();
}
return structure;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _HWiNFO_SHARED_MEM
{
public uint dwSignature;
public uint dwVersion;
public uint dwRevision;
public long poll_time;
public uint dwOffsetOfSensorSection;
public uint dwSizeOfSensorElement;
public uint dwNumSensorElements;
public uint dwOffsetOfReadingSection;
public uint dwSizeOfReadingElement;
public uint dwNumReadingElements;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _HWiNFO_SENSOR
{
public uint dwSensorID;
public uint dwSensorInst;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HWINFO_SENSORS_STRING_LEN)]
public string szSensorNameOrig;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HWINFO_SENSORS_STRING_LEN)]
public string szSensorNameUser;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _HWiNFO_ELEMENT
{
public SENSOR_READING_TYPE tReading;
public uint dwSensorIndex;
public uint dwSensorID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HWINFO_SENSORS_STRING_LEN)]
public string szLabelOrig;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HWINFO_SENSORS_STRING_LEN)]
public string szLabelUser;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HWINFO_UNIT_STRING_LEN)]
public string szUnit;
public double Value;
public double ValueMin;
public double ValueMax;
public double ValueAvg;
}
public enum SENSOR_READING_TYPE
{
SENSOR_TYPE_NONE,
SENSOR_TYPE_TEMP,
SENSOR_TYPE_VOLT,
SENSOR_TYPE_FAN,
SENSOR_TYPE_CURRENT,
SENSOR_TYPE_POWER,
SENSOR_TYPE_CLOCK,
SENSOR_TYPE_USAGE,
SENSOR_TYPE_OTHER,
}
public class HWInfoSensorSource
{
public HWInfoSensorSource(_HWiNFO_SENSOR _sensor) => Sensor = _sensor;
public _HWiNFO_SENSOR Sensor { get; }
public readonly List<HWInfoSensor> Sensors = new List<HWInfoSensor>();
}
public class HWInfoSensor
{
private readonly Func<_HWiNFO_ELEMENT> _getter;
public HWInfoSensor(Func<_HWiNFO_ELEMENT> getter) => _getter = getter;
public _HWiNFO_ELEMENT GetUpdatedElement() => _getter();
}
}
}