123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using System;
- using System.IO;
- using System.IO.MemoryMappedFiles;
- using System.Runtime.InteropServices;
- using System.Threading;
- using GpuFanControl.MsiAfterburnerWrap.ShareMemoryStructs;
- namespace GpuFanControl.MsiAfterburnerWrap
- {
- internal class MsiAfterBurnControlWrap : IDisposable
- {
- //const
- private const string ShareMemoryName = "MACMSharedMemory";
- private const string MutexName = "Global\\Access_MACMSharedMemory";
- private const uint HeaderSignature = ('M' << 24 | ('A' << 16) | ('C' << 8) | ('M'));
- private MemoryMappedFile _hMapFile;
- private MemoryMappedViewStream _pMapAddr;
- private byte[] _bufSnap;
- public void Connect()
- {
- //connect , failure throws FileNotFoundException
- _hMapFile = MemoryMappedFile.OpenExisting(ShareMemoryName, MemoryMappedFileRights.FullControl);
- _pMapAddr = _hMapFile.CreateViewStream();
- }
- public void Disconnect()
- {
- _pMapAddr?.Close();
- _hMapFile?.Dispose();
- }
- public void Refresh()
- {
- using (var m = new Mutex(false, MutexName))
- {
- m.WaitOne();
- var lenHeader = Marshal.SizeOf(typeof(MACM_SHARED_MEMORY_HEADER));
- var bufHeader = new byte[lenHeader];
- _pMapAddr.Seek(0, SeekOrigin.Begin);
- _pMapAddr.Read(bufHeader, 0, lenHeader);
- var stHeader = ByteArrayToStruct<MACM_SHARED_MEMORY_HEADER>(bufHeader);
- if (stHeader.Signature == HeaderSignature)
- {
- var lenSnap = stHeader.HeaderSize + stHeader.GpuEntryCount * stHeader.GpuEntrySize;
- var bufSnap = new byte[lenSnap];
- _pMapAddr.Seek(0, SeekOrigin.Begin);
- _pMapAddr.Read(bufSnap, 0, (int)lenSnap);
- _bufSnap = bufSnap;
- }
- m.ReleaseMutex();
- }
- }
- public void Commit()
- {
- using (var m = new Mutex(false, MutexName))
- {
- m.WaitOne();
- _pMapAddr.Seek(0, SeekOrigin.Begin);
- _pMapAddr.Write(_bufSnap, 0, _bufSnap.Length);
- _pMapAddr.Flush();
- _pMapAddr.Seek(0, SeekOrigin.Begin);
- var header = ByteArrayToStruct<MACM_SHARED_MEMORY_HEADER>(_bufSnap);
- header.Command = MACM_SHARED_MEMORY_COMMAND.FLUSH;
- StructToByteArray(header, _bufSnap);
- _pMapAddr.Seek(0, SeekOrigin.Begin);
- _pMapAddr.Write(_bufSnap, 0, _bufSnap.Length);
- _pMapAddr.Flush();
- m.ReleaseMutex();
- }
- Refresh();
- }
- public int GetNumberOfGpu()
- {
- var st = ByteArrayToStruct<MACM_SHARED_MEMORY_HEADER>(_bufSnap);
- return (int)st.GpuEntryCount;
- }
- public MACM_SHARED_MEMORY_GPU_ENTRY? GetGpuEntry(int index, out string error)
- {
- var header = ByteArrayToStruct<MACM_SHARED_MEMORY_HEADER>(_bufSnap);
- if (index > header.GpuEntryCount || index < 0)
- {
- error = "index out of range";
- return null;
- }
- var entry = ByteArrayToStruct<MACM_SHARED_MEMORY_GPU_ENTRY>(_bufSnap, (int)header.HeaderSize + index * (int)header.GpuEntrySize);
- error = null;
- return entry;
- }
- public string SetGpuEntry(MACM_SHARED_MEMORY_GPU_ENTRY entry, int index, bool flush = false)
- {
- var header = ByteArrayToStruct<MACM_SHARED_MEMORY_HEADER>(_bufSnap);
- if (index > header.GpuEntryCount || index < 0) return "index out of range";
- StructToByteArray(entry, _bufSnap, (int)(header.HeaderSize + index * header.GpuEntrySize));
- if (flush) Commit();
- return null;
- }
- private T ByteArrayToStruct<T>(byte[] bytes, int offset = 0)
- {
- GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
- T stuff;
- try
- {
- stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject() + offset, typeof(T));
- }
- finally
- {
- handle.Free();
- }
- return stuff;
- }
- private static void StructToByteArray<T>(T str, byte[] snap, int offset = 0)
- {
- var h = default(GCHandle);
- try
- {
- h = GCHandle.Alloc(snap, GCHandleType.Pinned);
- Marshal.StructureToPtr<T>(str, h.AddrOfPinnedObject() + offset, false);
- }
- finally
- {
- if (h.IsAllocated)
- {
- h.Free();
- }
- }
- }
- public void Dispose()
- {
- Disconnect();
- }
- }
- }
|