diff --git a/Plugins/PluginCoreTemp/CoreTempProxy.cpp b/Plugins/PluginCoreTemp/CoreTempProxy.cpp new file mode 100644 index 00000000..e2b8ac9f --- /dev/null +++ b/Plugins/PluginCoreTemp/CoreTempProxy.cpp @@ -0,0 +1,98 @@ +#include +#include "CoreTempProxy.h" + +CoreTempProxy::CoreTempProxy(void) +{ + memset(&this->m_pCoreTempData, 0, sizeof(CORE_TEMP_SHARED_DATA)); +} + +CoreTempProxy::~CoreTempProxy(void) +{ +} + +UINT CoreTempProxy::GetCoreLoad(int i_Index) const +{ + return this->m_pCoreTempData.uiLoad[i_Index]; +} + +UINT CoreTempProxy::GetTjMax(int i_Index) const +{ + return this->m_pCoreTempData.uiTjMax[i_Index]; +} + +UINT CoreTempProxy::GetCoreCount() const +{ + return this->m_pCoreTempData.uiCoreCnt; +} + +UINT CoreTempProxy::GetCPUCount() const +{ + return this->m_pCoreTempData.uiCPUCnt; +} + +float CoreTempProxy::GetTemp(int i_Index) const +{ + return this->m_pCoreTempData.fTemp[i_Index]; +} + +float CoreTempProxy::GetVID() const +{ + return this->m_pCoreTempData.fVID; +} + +float CoreTempProxy::GetCPUSpeed() const +{ + return this->m_pCoreTempData.fCPUSpeed; +} + +float CoreTempProxy::GetFSBSpeed() const +{ + return this->m_pCoreTempData.fFSBSpeed; +} + +float CoreTempProxy::GetMultiplier() const +{ + return this->m_pCoreTempData.fMultipier; +} + +LPCSTR CoreTempProxy::GetCPUName() const +{ + return this->m_pCoreTempData.sCPUName; +} + +bool CoreTempProxy::IsFahrenheit() const +{ + return this->m_pCoreTempData.ucFahrenheit != 0; +} + +bool CoreTempProxy::IsDistanceToTjMax() const +{ + return this->m_pCoreTempData.ucDeltaToTjMax != 0; +} + +const CORE_TEMP_SHARED_DATA &CoreTempProxy::GetDataStruct() const +{ + return this->m_pCoreTempData; +} + +bool CoreTempProxy::GetData() +{ + return this->m_SharedMem.ReadSharedMem(&this->m_pCoreTempData); +} + +LPCWSTR CoreTempProxy::GetErrorMessage() +{ + DWORD lastError; + + lastError = ::GetLastError(); + if ((lastError & UNKNOWN_EXCEPTION) > 0) + { + wcscpy_s(this->m_ErrorMessage, L"Unknown error occured while copying shared memory."); + } + else + { + ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastError, 0, this->m_ErrorMessage, 99, NULL); + } + + return this->m_ErrorMessage; +} \ No newline at end of file diff --git a/Plugins/PluginCoreTemp/CoreTempProxy.h b/Plugins/PluginCoreTemp/CoreTempProxy.h new file mode 100644 index 00000000..9017e12e --- /dev/null +++ b/Plugins/PluginCoreTemp/CoreTempProxy.h @@ -0,0 +1,34 @@ +#pragma once +#include "SharedMem.h" + +#define UNKNOWN_EXCEPTION 0x20000000 + +class CoreTempProxy +{ +public: + CoreTempProxy(void); + virtual ~CoreTempProxy(void); + + UINT GetCoreLoad(int i_Index) const; + UINT GetTjMax(int i_Index) const; + UINT GetCoreCount() const; + UINT GetCPUCount() const; + float GetTemp(int i_Index) const; + float GetVID() const; + float GetCPUSpeed() const; + float GetFSBSpeed() const; + float GetMultiplier() const; + LPCSTR GetCPUName() const; + bool IsFahrenheit() const; + bool IsDistanceToTjMax() const; + const CORE_TEMP_SHARED_DATA &GetDataStruct() const; + + bool GetData(); + DWORD GetDllError() const { return GetLastError(); } + LPCWSTR GetErrorMessage(); +private: + + CSharedMemClient m_SharedMem; + CORE_TEMP_SHARED_DATA m_pCoreTempData; + WCHAR m_ErrorMessage[100]; +}; diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.cpp b/Plugins/PluginCoreTemp/PluginCoreTemp.cpp new file mode 100644 index 00000000..6bb133a1 --- /dev/null +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.cpp @@ -0,0 +1,318 @@ +/* + Copyright (C) 2011 Arthur Liberman + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include "CoreTempProxy.h" + +#include "..\..\Library\Export.h" // Rainmeter's exported functions + +extern "C" +{ + __declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); + __declspec( dllexport ) void Finalize(HMODULE instance, UINT id); + __declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); + __declspec( dllexport ) double Update2(UINT id); + __declspec( dllexport ) UINT GetPluginVersion(); + __declspec( dllexport ) LPCTSTR GetPluginAuthor(); +} + +typedef enum eMeasureType +{ + MeasureTemperature, + MeasureMaxTemperature, + MeasureTjMax, + MeasureLoad, + MeasureVid, + MeasureCpuSpeed, + MeasureBusSpeed, + MeasureBusMultiplier, + MeasureCpuName +}; + +std::map g_Types; +std::map g_Indexes; +CoreTempProxy proxy; + +eMeasureType convertStringToMeasureType(LPCWSTR i_String); +bool areStringsEqual(LPCWSTR i_String1, LPCWSTR i_Strting2); +double getValues(UINT i_Id); +LPCTSTR getString(UINT i_Id); +float getHighestTemp(); + +/* + This function is called when the measure is initialized. + The function must return the maximum value that can be measured. + The return value can also be 0, which means that Rainmeter will + track the maximum value automatically. The parameters for this + function are: + + instance The instance of this DLL + iniFile The name of the ini-file (usually Rainmeter.ini) + section The name of the section in the ini-file for this measure + id The identifier for the measure. This is used to identify the measures that use the same plugin. +*/ +UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +{ + /* + Read our own settings from the ini-file + The ReadConfigString can be used for this purpose. Plugins + can also read the config some other way (e.g. with + GetPrivateProfileInt, but in that case the variables + do not work. + */ + LPCTSTR data = ReadConfigString(section, L"CoreTempType", L"Temperature"); + if (data) + { + eMeasureType type = convertStringToMeasureType(data); + + g_Types[id] = type; + if (type == MeasureTemperature || type == MeasureTjMax || type == MeasureLoad) + { + data = ReadConfigString(section, L"CoreTempIndex", L"0"); + if (data) + { + g_Indexes[id] = _wtoi(data); + } + else + { + g_Indexes[id] = 0; + LSLog(LOG_WARNING, L"Rainmeter", L"CoreTempPlugin: Selected CoreTempType requires CoreTempIndex, assuming 0."); + } + } + } + + return 0; +} + +/* + This function is called when new value should be measured. + The function returns the new value. +*/ +double Update2(UINT id) +{ + double result = 0; + + if (proxy.GetData()) + { + result = getValues(id); + } + + return result; +} + +LPCTSTR GetString(UINT id, UINT flags) +{ + return getString(id); +} + +/* + If the measure needs to free resources before quitting. + The plugin can export Finalize function, which is called + when Rainmeter quits (or refreshes). +*/ +void Finalize(HMODULE instance, UINT id) +{ + /* Nothing to do here */ +} + +/* + Returns the version number of the plugin. The value + can be calculated like this: Major * 1000 + Minor. + So, e.g. 2.31 would be 2031. +*/ +UINT GetPluginVersion() +{ + return 1000; +} + +/* + Returns the author of the plugin for the about dialog. +*/ +LPCTSTR GetPluginAuthor() +{ + return L"Arthur Liberman - ALCPU (arthur_liberman@hotmail.com)"; +} + +bool areStringsEqual(LPCWSTR i_String1, LPCWSTR i_Strting2) +{ + return _wcsicmp(i_String1, i_Strting2) == 0; +} + +eMeasureType convertStringToMeasureType(LPCWSTR i_String) +{ + eMeasureType result; + + if (areStringsEqual(i_String, L"Temperature")) + { + result = MeasureTemperature; + } + else if (areStringsEqual(i_String, L"MaxTemperature")) + { + result = MeasureMaxTemperature; + } + else if (areStringsEqual(i_String, L"TjMax")) + { + result = MeasureTjMax; + } + else if (areStringsEqual(i_String, L"Load")) + { + result = MeasureLoad; + } + else if (areStringsEqual(i_String, L"Vid")) + { + result = MeasureVid; + } + else if (areStringsEqual(i_String, L"CpuSpeed")) + { + result = MeasureCpuSpeed; + } + else if (areStringsEqual(i_String, L"BusSpeed")) + { + result = MeasureBusSpeed; + } + else if (areStringsEqual(i_String, L"BusMultiplier")) + { + result = MeasureBusMultiplier; + } + else if (areStringsEqual(i_String, L"CpuName")) + { + result = MeasureCpuName; + } + else + { + result = MeasureTemperature; + LSLog(LOG_WARNING, L"Rainmeter", L"CoreTempPlugin: Incorrect CoreTempType, assuming Temperature."); + } + + return result; +} + +float getHighestTemp() +{ + float temp = -255; + UINT coreCount = proxy.GetCoreCount(); + + for (UINT i = 0; i < coreCount; ++i) + { + if (temp < proxy.GetTemp(i)) + { + temp = proxy.GetTemp(i); + } + } + + return temp; +} + +double getValues(UINT i_Id) +{ + double value; + + switch (g_Types[i_Id]) + { + case MeasureTemperature: + value = proxy.GetTemp(g_Indexes[i_Id]); + break; + + case MeasureMaxTemperature: + value = getHighestTemp(); + break; + + case MeasureTjMax: + value = proxy.GetTjMax(g_Indexes[i_Id]); + break; + + case MeasureLoad: + value = proxy.GetCoreLoad(g_Indexes[i_Id]); + break; + + case MeasureVid: + value = proxy.GetVID(); + break; + + case MeasureCpuSpeed: + value = proxy.GetCPUSpeed(); + break; + + case MeasureBusSpeed: + value = proxy.GetFSBSpeed(); + break; + + case MeasureBusMultiplier: + value = proxy.GetMultiplier(); + break; + + default: + value = 0; + break; + } + + return value; +} + +LPCTSTR getString(UINT i_Id) +{ + static TCHAR string[1000]; + + switch (g_Types[i_Id]) + { + case MeasureTemperature: + _stprintf_s(string, L"%.0f", proxy.GetTemp(g_Indexes[i_Id])); + break; + + case MeasureMaxTemperature: + _stprintf_s(string, L"%.0f", getHighestTemp()); + break; + + case MeasureTjMax: + _stprintf_s(string, L"%d", proxy.GetTjMax(g_Indexes[i_Id])); + break; + + case MeasureLoad: + _stprintf_s(string, L"%d", proxy.GetCoreLoad(g_Indexes[i_Id])); + break; + + case MeasureVid: + _stprintf_s(string, L"%.4f", proxy.GetVID()); + break; + + case MeasureCpuSpeed: + _stprintf_s(string, L"%.2f", proxy.GetCPUSpeed()); + break; + + case MeasureBusSpeed: + _stprintf_s(string, L"%.2f", proxy.GetFSBSpeed()); + break; + + case MeasureBusMultiplier: + _stprintf_s(string, L"%.1f", proxy.GetMultiplier()); + break; + + case MeasureCpuName: + _stprintf_s(string, L"%S", proxy.GetCPUName()); + break; + + default: + string[0] = '\0'; + break; + } + + return string; +} \ No newline at end of file diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.rc b/Plugins/PluginCoreTemp/PluginCoreTemp.rc new file mode 100644 index 00000000..afdf3d69 --- /dev/null +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.rc @@ -0,0 +1,48 @@ +// Microsoft Developer Studio generated resource script. +// + +#include "..\..\revision-number.h" +#define APSTUDIO_READONLY_SYMBOLS +#include "windows.h" +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "FileDescription", "CoreTemp Plugin for Rainmeter" + VALUE "FileVersion", "1.0.0.0" + VALUE "InternalName", "PluginCoreTemp" + VALUE "LegalCopyright", "Copyright (C) 2011 - Arthur Liberman" + VALUE "OriginalFilename", "CoreTemp.dll" + VALUE "ProductName", "Rainmeter" +#ifdef _WIN64 + VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" +#else + VALUE "ProductVersion", STRPRODUCTVER " (32-bit)" +#endif //_WIN64 + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.vcproj b/Plugins/PluginCoreTemp/PluginCoreTemp.vcproj new file mode 100644 index 00000000..f7ea1acf --- /dev/null +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.vcproj @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/PluginCoreTemp/SharedMem.cpp b/Plugins/PluginCoreTemp/SharedMem.cpp new file mode 100644 index 00000000..300d5a57 --- /dev/null +++ b/Plugins/PluginCoreTemp/SharedMem.cpp @@ -0,0 +1,63 @@ +#include +#include "SharedMem.h" + +CSharedMemClient::CSharedMemClient(void) +{ +} + +CSharedMemClient::~CSharedMemClient(void) +{ +} + +bool CSharedMemClient::ReadSharedMem(PCORE_TEMP_SHARED_DATA i_SharedData) +{ + bool bRet = false; + PCORE_TEMP_SHARED_DATA pSharedData; + HANDLE hdlMemory; + HANDLE hdlMutex; + + hdlMutex = CreateMutex(NULL,FALSE,CORE_TEMP_MUTEX_OBJECT); + if (hdlMutex == NULL) + { + return false; + } + + WaitForSingleObject(hdlMutex, INFINITE); + + hdlMemory = OpenFileMapping( + FILE_MAP_READ, // Read only permission. + TRUE, + CORE_TEMP_MAPPING_OBJECT); // "CoreTempMappingObject" + + if (hdlMemory == NULL) + { + ReleaseMutex(hdlMutex); + return false; + } + + pSharedData = (PCORE_TEMP_SHARED_DATA)MapViewOfFile(hdlMemory, FILE_MAP_READ, 0, 0, 0); + if (pSharedData == NULL) + { + ReleaseMutex(hdlMutex); + CloseHandle(hdlMemory); + hdlMemory = NULL; + return false; + } + + __try + { + memcpy_s(i_SharedData, sizeof(core_temp_shared_data), pSharedData, sizeof(core_temp_shared_data)); + bRet = true; + } + __except(1) + { + bRet = false; + SetLastError(0x20000000); //Unknown error + } + + UnmapViewOfFile(pSharedData); + CloseHandle(hdlMemory); + ReleaseMutex(hdlMutex); + + return bRet; +} \ No newline at end of file diff --git a/Plugins/PluginCoreTemp/SharedMem.h b/Plugins/PluginCoreTemp/SharedMem.h new file mode 100644 index 00000000..8c9110fd --- /dev/null +++ b/Plugins/PluginCoreTemp/SharedMem.h @@ -0,0 +1,41 @@ +// Common.h: +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_COMMON_H__B302F7F1_E8D6_4EF2_9D89_A634D14922BF__INCLUDED_) +#define AFX_COMMON_H__B302F7F1_E8D6_4EF2_9D89_A634D14922BF__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define CORE_TEMP_MAPPING_OBJECT L"CoreTempMappingObject" +#define CORE_TEMP_MUTEX_OBJECT L"CoreTempMutexObject" + +typedef struct core_temp_shared_data +{ + unsigned int uiLoad[256]; + unsigned int uiTjMax[128]; + unsigned int uiCoreCnt; + unsigned int uiCPUCnt; + float fTemp[256]; + float fVID; + float fCPUSpeed; + float fFSBSpeed; + float fMultipier; + char sCPUName[100]; + unsigned char ucFahrenheit; + unsigned char ucDeltaToTjMax; +}CORE_TEMP_SHARED_DATA,*PCORE_TEMP_SHARED_DATA,**PPCORE_TEMP_SHARED_DATA; + +class CSharedMemClient +{ +// Construction +public: + CSharedMemClient(void); // standard constructor + virtual ~CSharedMemClient(void); + + bool ReadSharedMem(PCORE_TEMP_SHARED_DATA i_SharedData); +}; + +#endif // !defined(AFX_COMMON_H__B302F7F1_E8D6_4EF2_9D89_A634D14922BF__INCLUDED_) diff --git a/Rainmeter.sln b/Rainmeter.sln index b99ec9cd..c6000e3c 100644 --- a/Rainmeter.sln +++ b/Rainmeter.sln @@ -97,6 +97,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginFolderInfo", "Plugins {BE9D2400-7F1C-49D6-8498-5CE495491AD6} = {BE9D2400-7F1C-49D6-8498-5CE495491AD6} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginCoreTemp", "Plugins\PluginCoreTemp\PluginCoreTemp.vcproj", "{F32FA418-8DF4-4E94-B92B-EBD502F5DC07}" + ProjectSection(ProjectDependencies) = postProject + {BE9D2400-7F1C-49D6-8498-5CE495491AD6} = {BE9D2400-7F1C-49D6-8498-5CE495491AD6} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -265,6 +270,14 @@ Global {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.Build.0 = Release|Win32 {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.ActiveCfg = Release|x64 {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.Build.0 = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.ActiveCfg = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.Build.0 = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.ActiveCfg = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.Build.0 = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.ActiveCfg = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.Build.0 = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.ActiveCfg = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE