bool InitCom() { if (!com_initialized) com_initialized = SUCCEEDED(CoInitialize(0)); if (!com_initialized) { RmLog(LOG_ERROR, L"Win7AudioPlugin.dll: COM initialization failed"); return false; } HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, 0, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); instance_created = (S_OK == hr && pEnumerator); if (!instance_created) { std::wstring dbg_str = L"Win7AudioPlugin.dll: COM creation failed"; if (hr == REGDB_E_CLASSNOTREG) dbg_str += L" REGDB_E_CLASSNOTREG"; else if (hr == CLASS_E_NOAGGREGATION) dbg_str += L" CLASS_E_NOAGGREGATION"; else if (hr == E_NOINTERFACE) dbg_str += L" E_NOINTERFACE"; else { static WCHAR e_code[256]; wsprintf(e_code, L" %li", (long)hr); dbg_str += e_code; } RmLog(LOG_ERROR, dbg_str.c_str()); return CleanUp() != 0; } if (S_OK != pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pCollection) || !pCollection) { RmLog(LOG_WARNING, L"Win7AudioPlugin.dll: Could not enumerate AudioEndpoints"); return CleanUp() != 0; } return true; }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; LPCWSTR value = RmReadString(rm, L"DestAddress", L""); if (*value) { int strLen = (int)wcslen(value) + 1; int bufLen = WideCharToMultiByte(CP_ACP, 0, value, strLen, NULL, 0, NULL, NULL); if (bufLen > 0) { char* buffer = new char[bufLen]; WideCharToMultiByte(CP_ACP, 0, value, strLen, buffer, bufLen, NULL, NULL); measure->destAddr = inet_addr(buffer); if (measure->destAddr == INADDR_NONE) { WSADATA wsaData; if (WSAStartup(0x0101, &wsaData) == 0) { LPHOSTENT pHost = gethostbyname(buffer); if (pHost) { measure->destAddr = *(DWORD*)pHost->h_addr; } else { RmLog(LOG_WARNING, L"PingPlugin.dll: Unable to get host by name"); } WSACleanup(); } else { RmLog(LOG_WARNING, L"PingPlugin.dll: Unable to start WSA"); } } delete [] buffer; } } measure->updateRate = RmReadInt(rm, L"UpdateRate", 32); measure->timeout = RmReadInt(rm, L"Timeout", 30000); measure->timeoutValue = RmReadDouble(rm, L"TimeoutValue", 30000.0); measure->finishAction = RmReadString(rm, L"FinishAction", L"", false); measure->skin = RmGetSkin(rm); }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { Measure* measure = (Measure*)data; LPCWSTR value = RmReadString(rm, L"Type", L""); if (_wcsicmp(value, L"Major") == 0) { measure->type = MEASURE_MAJOR; } else if (_wcsicmp(value, L"Minor") == 0) { measure->type = MEASURE_MINOR; } else if (_wcsicmp(value, L"Number") == 0) { measure->type = MEASURE_NUMBER; } else if (_wcsicmp(value, L"String") == 0) { measure->type = MEASURE_STRING; } else { RmLog(LOG_ERROR, L"SystemVersion.dll: Invalid Type="); } }
PLUGIN_EXPORT void ExecuteBang(LPCTSTR args, UINT id) { if (_wcsicmp(args, L"NextTrack") == 0) { SendKey(VK_MEDIA_NEXT_TRACK); } else if (_wcsicmp(args, L"PrevTrack") == 0) { SendKey(VK_MEDIA_PREV_TRACK); } else if (_wcsicmp(args, L"Stop") == 0) { SendKey(VK_MEDIA_STOP); } else if (_wcsicmp(args, L"PlayPause") == 0) { SendKey(VK_MEDIA_PLAY_PAUSE); } else if (_wcsicmp(args, L"VolumeMute") == 0) { SendKey(VK_VOLUME_MUTE); } else if (_wcsicmp(args, L"VolumeDown") == 0) { SendKey(VK_VOLUME_DOWN); } else if (_wcsicmp(args, L"VolumeUp") == 0) { SendKey(VK_VOLUME_UP); } else { RmLog(LOG_WARNING, L"MediaKey.dll: Unknown bang"); } }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; LPCWSTR type = RmReadString(rm, L"ResCountType", L"GDI"); if (_wcsicmp(L"GDI", type) == 0) { measure->type = GDI_COUNT; } else if (_wcsicmp(L"USER", type) == 0) { measure->type = USER_COUNT; } else if (_wcsicmp(L"HANDLE", type) == 0) { measure->type = HANDLE_COUNT; } else if (_wcsicmp(L"WINDOW", type) == 0) { measure->type = WINDOW_COUNT; } else { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"ResMon.dll: GDICountType=%s is not valid in [%s]", type, RmGetMeasureName(rm)); RmLog(LOG_ERROR, buffer); } measure->process = RmReadString(rm, L"ProcessName", L""); }
PLUGIN_EXPORT void Initialize(void** data, void* rm) { ChildMeasure* child = new ChildMeasure; *data = child; void* skin = RmGetSkin(rm); LPCWSTR parentName = RmReadString(rm, L"ParentName", L""); if (!*parentName) { child->parent = new ParentMeasure; child->parent->name = RmGetMeasureName(rm); child->parent->skin = skin; child->parent->ownerChild = child; g_ParentMeasures.push_back(child->parent); } else { // Find parent using name AND the skin handle to be sure that it's the right one std::vector<ParentMeasure*>::const_iterator iter = g_ParentMeasures.begin(); for ( ; iter != g_ParentMeasures.end(); ++iter) { if (_wcsicmp((*iter)->name, parentName) == 0 && (*iter)->skin == skin) { child->parent = (*iter); return; } } RmLog(LOG_ERROR, L"ParentChild.dll: Invalid ParentName="); } }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; LPCWSTR type = RmReadString(rm, L"SpeedFanType", L"TEMPERATURE"); if (_wcsicmp(L"TEMPERATURE", type) == 0) { measure->type = TYPE_TEMP; LPCWSTR scale = RmReadString(rm, L"SpeedFanScale", L"C"); if (_wcsicmp(L"C", scale) == 0) { measure->scale = SCALE_CENTIGRADE; } else if (_wcsicmp(L"F", scale) == 0) { measure->scale = SCALE_FARENHEIT; } else if (_wcsicmp(L"K", scale) == 0) { measure->scale = SCALE_KELVIN; } else { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"SpeedFanPlugin.dll: SpeedFanScale=%s is not valid in [%s]", scale, RmGetMeasureName(rm)); RmLog(LOG_ERROR, buffer); } } else if (_wcsicmp(L"FAN", type) == 0) { measure->type = TYPE_FAN; } else if (_wcsicmp(L"VOLTAGE", type) == 0) { measure->type = TYPE_VOLT; } else { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"SpeedFanPlugin.dll: SpeedFanType=%s is not valid in [%s]", type, RmGetMeasureName(rm)); RmLog(LOG_ERROR, buffer); } measure->number = RmReadInt(rm, L"SpeedFanNumber", 0); }
/* Get the data from shared memory. */ void ReadSharedData(SensorType type, ScaleType scale, UINT number, double* value) { HANDLE hData = OpenFileMapping(FILE_MAP_READ, FALSE, L"SFSharedMemory_ALM"); if (hData == nullptr) return; SpeedFanData* ptr = (SpeedFanData*)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0); if (ptr == 0) { CloseHandle(hData); return; } if (ptr->version == 1) { switch(type) { case TYPE_TEMP: if (number < ptr->NumTemps) { *value = ptr->temps[number]; *value /= 100.0; if (scale == SCALE_FARENHEIT) { *value *= 1.8; *value += 32.0; } else if (scale == SCALE_KELVIN) { *value += 273.15; } } break; case TYPE_FAN: if (number < ptr->NumTemps) { *value = ptr->fans[number]; } break; case TYPE_VOLT: if (number < ptr->NumVolts) { *value = ptr->volts[number]; *value /= 100.0; } break; } } else { RmLog(LOG_ERROR, L"SpeedFanPlugin.dll: Incorrect shared memory version"); } UnmapViewOfFile(ptr); CloseHandle(hData); }
PLUGIN_EXPORT void Initialize(void** data, void* rm) { MeasureData* measure = new MeasureData; *data = measure; ++g_Instances; if (g_Instances == 1) { WCHAR buffer[256]; // Create WINLAN API Handle if (g_hClient == nullptr) { DWORD dwNegotiatedVersion = 0; DWORD dwErr = WlanOpenHandle(WLAN_API_VERSION, nullptr, &dwNegotiatedVersion, &g_hClient); if (ERROR_SUCCESS != dwErr) { FinalizeHandle(); _snwprintf_s(buffer, _TRUNCATE, L"WifiStatus.dll: Unable to open WLAN API Handle. Error code (%u): %s", dwErr, ToErrorString(dwErr)); RmLog(LOG_ERROR, buffer); return; } } // Query list of WLAN interfaces if (g_pIntfList == nullptr) { DWORD dwErr = WlanEnumInterfaces(g_hClient, nullptr, &g_pIntfList); if (ERROR_SUCCESS != dwErr) { FinalizeHandle(); _snwprintf_s(buffer, _TRUNCATE, L"WifiStatus.dll: Unable to find any WLAN interfaces/adapters. Error code %u", dwErr); RmLog(LOG_ERROR, buffer); return; } else if (g_pIntfList->dwNumberOfItems == 0) { FinalizeHandle(); RmLog(LOG_ERROR, L"WifiStatus.dll: No WLAN interfaces/adapters available."); return; } } } }
static PyObject *Rainmeter_RmLog(RainmeterObject *self, PyObject *args) { int level; PyObject *message; PyArg_ParseTuple(args, "iU", &level, &message); wchar_t *messageStr = PyUnicode_AsWideCharString(message, NULL); RmLog(level, messageStr); PyMem_Free(messageStr); Py_INCREF(Py_None); return Py_None; }
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { MeasureData* measure = (MeasureData*)data; const WCHAR* pos = wcschr(args, L' '); if (pos) { size_t len = pos - args; if (_wcsnicmp(args, L"SendMessage", len) == 0) { ++pos; // Parse parameters DWORD uMsg, wParam, lParam; if (3 == swscanf(pos, L"%u %u %u", &uMsg, &wParam, &lParam)) { HWND hwnd = FindWindow( measure->windowClass.empty() ? nullptr : measure->windowClass.c_str(), measure->windowName.empty() ? nullptr : measure->windowName.c_str()); if (hwnd) { PostMessage(hwnd, uMsg, wParam, lParam); } else { RmLog(LOG_ERROR, L"WindowMessagePlugin.dll: Unable to find window"); } } else { RmLog(LOG_WARNING, L"WindowMessagePlugin.dll: Incorrect number of arguments for bang"); } return; } } RmLog(LOG_WARNING, L"WindowMessagePlugin.dll: Unknown bang"); }
/* ** Initialize internet handle and crtical section. ** */ void CInternet::Initialize() { c_NetHandle = InternetOpen(L"Rainmeter NowPlaying.dll", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!c_NetHandle) { RmLog(LOG_ERROR, L"NowPlaying.dll: Unable to open net handle"); } }
PLUGIN_EXPORT void Initialize(void** data, void* rm) { RmLog(LOG_DEBUG, L"RainFbx.dll: Initialize"); FbxMeasureConf* measureConfig = new FbxMeasureConf; *data = measureConfig; void* skin = RmGetSkin(rm); LPCWSTR fbxAPIConf = RmReadString(rm, L"FbxAPIConf", L""); if (!*fbxAPIConf) { /* [FbxAPIConf] (parent) */ RmLog(LOG_DEBUG, L"RainFbx.dll: Reading [FbxAPIConf] (parent)"); measureConfig->fbxAPIConf = new FbxAPIConf; measureConfig->fbxAPIConf->section = RmGetMeasureName(rm); measureConfig->fbxAPIConf->skin = skin; measureConfig->fbxAPIConf->lastConfig = measureConfig; g_FbxAPIConfs.push_back(measureConfig->fbxAPIConf); fbx.app_token = RmReadString(rm, L"AppToken", L""); if(fbx.app_token == L"") writeAppToken = true; fbx.setHostname(RmReadString(rm, L"Hostname", L"")); } else { /* [FbxMeasureConf] (child) */ RmLog(LOG_DEBUG, L"RainFbx.dll: Reading [FbxMeasureConf] (child)"); // Find parent using name AND the skin handle to be sure that it's the right one std::vector<FbxAPIConf*>::const_iterator iter = g_FbxAPIConfs.begin(); for (; iter != g_FbxAPIConfs.end(); ++iter) { if ( ( (*iter)->section == fbxAPIConf ) && ( (*iter)->skin == skin ) ) { measureConfig->section = RmGetMeasureName(rm); measureConfig->fbxAPIConf = (*iter); return; } } RmLog(LOG_ERROR, L"RainFbx.dll: Invalid FbxAPIConf="); } }
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; RmLog(LOG_WARNING, L"CoreTemp.dll: Invalid CoreTempType"); } return result; }
// Fetches the data from the net and parses the page unsigned __stdcall NetworkThreadProc(void* pParam) { MeasureData* measure = (MeasureData*)pParam; DWORD dwSize = 0; RmLogF(measure->rm, LOG_DEBUG, L"WebParser: Fetching: %s", measure->url.c_str()); BYTE* data = DownloadUrl(measure->proxy.handle, measure->url, &dwSize, measure->forceReload); if (!data) { ShowError(measure->rm, L"Fetch error"); if (!measure->onConnectErrAction.empty()) { RmExecute(measure->skin, measure->onConnectErrAction.c_str()); } } else { if (measure->debug == 2) { // Dump to a file FILE* file = _wfopen(measure->debugFileLocation.c_str(), L"wb"); if (file) { fwrite(data, sizeof(BYTE), dwSize, file); fclose(file); } else { RmLog(measure->rm, LOG_ERROR, L"WebParser: Failed to dump debug data"); } } ParseData(measure, data, dwSize); free(data); } EnterCriticalSection(&g_CriticalSection); CloseHandle(measure->threadHandle); measure->threadHandle = 0; LeaveCriticalSection(&g_CriticalSection); return 0; // thread completed successfully }
/* ** Default implementation for getting lyrics. ** */ void Player::FindLyrics() { if (!m_InternetThread) { m_Lyrics.clear(); unsigned int id; HANDLE thread = (HANDLE)_beginthreadex(nullptr, 0, LyricsThreadProc, this, 0, &id); if (thread) { m_InternetThread = thread; } else { RmLog(LOG_DEBUG, L"NowPlaying.dll: Failed to start lyrics thread"); } } }
HINTERNET CreateProxy(LPCWSTR proxyName) { DWORD proxyType; LPCWSTR proxyServer; if (_wcsicmp(proxyName, L"/auto") == 0) { proxyType = INTERNET_OPEN_TYPE_PRECONFIG; proxyServer = nullptr; } else if (_wcsicmp(proxyName, L"/none") == 0) { proxyType = INTERNET_OPEN_TYPE_DIRECT; proxyServer = nullptr; } else { proxyType = INTERNET_OPEN_TYPE_PROXY; proxyServer = proxyName; } HINTERNET handle = InternetOpen(L"Rainmeter WebParser plugin", proxyType, proxyServer, nullptr, 0); if (handle) { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"WebParser: ProxyServer=\"%s\" (type=%s, handle=0x%p)", proxyName, proxyType == INTERNET_OPEN_TYPE_PRECONFIG ? L"PRECONFIG" : proxyType == INTERNET_OPEN_TYPE_DIRECT ? L"DIRECT" : L"PROXY", handle); RmLog(LOG_DEBUG, buffer); } else { ShowError(__LINE__); } return handle; }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; LPCWSTR value = RmReadString(rm, L"RecycleType", L"COUNT"); if (_wcsicmp(L"COUNT", value) == 0) { measure->count = true; } else if (_wcsicmp(L"SIZE", value) == 0) { measure->count = false; } else { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"RecycleManager.dll: RecycleType=%s is not valid in [%s]", value, RmGetMeasureName(rm)); RmLog(LOG_ERROR, buffer); } }
// Fetches the data from the net and parses the page unsigned __stdcall NetworkThreadProc(void* pParam) { MeasureData* measure = (MeasureData*)pParam; DWORD dwSize = 0; BYTE* data = DownloadUrl(measure->proxy.handle, measure->url, &dwSize, measure->forceReload); if (data) { if (measure->debug == 2) { // Dump to a file FILE* file = _wfopen(measure->debugFileLocation.c_str(), L"wb"); if (file) { fwrite(data, sizeof(BYTE), dwSize, file); fclose(file); } else { std::wstring log = L"WebParser.dll: ["; log += measure->section; log += L"] Failed to dump debug data: "; log += measure->debugFileLocation; RmLog(LOG_ERROR, log.c_str()); } } ParseData(measure, (LPCSTR)data, dwSize); free(data); } EnterCriticalSection(&g_CriticalSection); CloseHandle(measure->threadHandle); measure->threadHandle = 0; LeaveCriticalSection(&g_CriticalSection); return 0; // thread completed successfully }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { ChildMeasure* child = (ChildMeasure*)data; ParentMeasure* parent = child->parent; if (!parent) { return; } // Read common options LPCWSTR type = RmReadString(rm, L"Type", L""); if (_wcsicmp(type, L"A") == 0) { child->type = MEASURE_A; } else if (_wcsicmp(type, L"B") == 0) { child->type = MEASURE_B; } else if (_wcsicmp(type, L"C") == 0) { child->type = MEASURE_C; } else { RmLog(LOG_ERROR, L"ParentChild.dll: Invalid Type="); } // Read parent specific options if (parent->ownerChild == child) { parent->valueA = RmReadInt(rm, L"ValueA", 0); parent->valueB = RmReadInt(rm, L"ValueB", 0); parent->valueC = RmReadInt(rm, L"ValueC", 0); } }
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { Measure* measure = (Measure*)data; Player* player = measure->player; if (!_wcsnicmp(args, L"Open",4)) { player->OpenPlayer(measure->playerpath); } else if (player->GetStatus()) { if (!_wcsnicmp(args, L"Close",5)) { player->ClosePlayer(); } else if (!_wcsicmp(args, L"Restore")) { player->RestorePlayer(); } else if (!_wcsicmp(args, L"Minimize")) { player->MinimizePlayer(); } else if (!_wcsicmp(args, L"PlayPause")) { player->PlayPause(); } else if (!_wcsicmp(args, L"Stop")) { player->Stop(); } else if (!_wcsicmp(args, L"Previous")) { player->Previous(); } else if (!_wcsicmp(args, L"Next")) { player->Next(); } else if (!_wcsicmp(args, L"VolumeMute")) { player->VolumeMute(); } else if (!_wcsicmp(args, L"VolumeUp")) { player->VolumeUp(); } else if (!_wcsicmp(args, L"VolumeDown")) { player->VolumeDown(); } else if (!_wcsnicmp(args, L"Hide",4)) { player->HideToTray(); } else if (!_wcsicmp(args, L"MiniMode")) { player->MiniMode(); } else { player->ExecuteBang(args); } } else { RmLog(LOG_WARNING, L"MusicPlayer.dll: Player isn't running"); } }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; EnterCriticalSection(&g_CriticalSection); /* Read our own settings from the ini-file */ std::wstring url = RmReadString(rm, L"Url", L"", FALSE); std::wstring::size_type start = 0; while ((start = url.find(L"[&", start)) != std::wstring::npos) { std::wstring::size_type si = start + 1; std::wstring::size_type end = url.find(L']', si); if (end == std::wstring::npos) break; std::wstring var = L"["; var.append(url, si + 1, end - si); const WCHAR* result = RmReplaceVariables(rm, var.c_str()); const size_t resultLength = wcslen(result); url.replace(start, end - start + 1, result, resultLength); start += resultLength; } measure->url = url; measure->regExp = RmReadString(rm, L"RegExp", L""); measure->finishAction = RmReadString(rm, L"FinishAction", L"", FALSE); measure->onRegExpErrAction = RmReadString(rm, L"OnRegExpErrorAction", L"", FALSE); measure->onConnectErrAction = RmReadString(rm, L"OnConnectErrorAction", L"", FALSE); measure->onDownloadErrAction = RmReadString(rm, L"OnDownloadErrorAction", L"", FALSE); measure->errorString = RmReadString(rm, L"ErrorString", L""); int index = RmReadInt(rm, L"StringIndex", 0); measure->stringIndex = index < 0 ? 0 : index; index = RmReadInt(rm, L"StringIndex2", 0); measure->stringIndex2 = index < 0 ? 0 : index; measure->decodeCharacterReference = RmReadInt(rm, L"DecodeCharacterReference", 0); measure->updateRate = RmReadInt(rm, L"UpdateRate", 600); measure->forceReload = 0!=RmReadInt(rm, L"ForceReload", 0); measure->codepage = RmReadInt(rm, L"CodePage", 0); if (measure->codepage == 0) { measure->codepage = CP_UTF8; } measure->download = 0!=RmReadInt(rm, L"Download", 0); if (measure->download) { measure->downloadFolder = RmPathToAbsolute(rm, L"DownloadFile\\"); measure->downloadFile = RmReadString(rm, L"DownloadFile", L""); } else { measure->downloadFile.clear(); } measure->debug = RmReadInt(rm, L"Debug", 0); if (measure->debug == 2) { measure->debugFileLocation = RmReadPath(rm, L"Debug2File", L"WebParserDump.txt"); RmLog(rm, LOG_DEBUG, measure->debugFileLocation.c_str()); } LeaveCriticalSection(&g_CriticalSection); }
void ParseData(MeasureData* measure, const BYTE* rawData, DWORD rawSize, bool utf16Data) { const int UTF16_CODEPAGE = 1200; if (measure->codepage == UTF16_CODEPAGE) { utf16Data = true; } const char* error; int erroffset; int ovector[OVECCOUNT]; int rc; bool doErrorAction = false; // Compile the regular expression in the first argument pcre16* re = pcre16_compile( (PCRE_SPTR16)measure->regExp.c_str(), PCRE_UTF16, &error, &erroffset, nullptr); if (re != nullptr) { // Compilation succeeded: match the subject in the second argument std::wstring buffer; auto data = (const WCHAR*)rawData; DWORD dataLength = rawSize / 2; if (!utf16Data) { buffer = StringUtil::Widen((LPCSTR)rawData, rawSize, measure->codepage); data = buffer.c_str(); dataLength = (DWORD)buffer.length(); } rc = pcre16_exec(re, nullptr, (PCRE_SPTR16)data, dataLength, 0, 0, ovector, OVECCOUNT); if (rc >= 0) { if (rc == 0) { // The output vector wasn't big enough RmLog(measure->rm, LOG_ERROR, L"WebParser: Too many substrings"); } else { if (measure->stringIndex < rc) { if (measure->debug != 0) { for (int i = 0; i < rc; ++i) { const WCHAR* match = data + ovector[2 * i]; const int matchLen = min(ovector[2 * i + 1] - ovector[2 * i], 256); RmLogF(measure->rm, LOG_DEBUG, L"WebParser: Index %2d: %.*s", i, matchLen, match); } } const WCHAR* match = data + ovector[2 * measure->stringIndex]; int matchLen = ovector[2 * measure->stringIndex + 1] - ovector[2 * measure->stringIndex]; EnterCriticalSection(&g_CriticalSection); measure->resultString.assign(match, matchLen); DecodeReferences(measure->resultString, measure->decodeCharacterReference); LeaveCriticalSection(&g_CriticalSection); } else { RmLog(measure->rm, LOG_WARNING, L"WebParser: Not enough substrings"); // Clear the old result EnterCriticalSection(&g_CriticalSection); measure->resultString.clear(); if (measure->download) { if (measure->downloadFile.empty()) // cache mode { if (!measure->downloadedFile.empty()) { // Delete old downloaded file DeleteFile(measure->downloadedFile.c_str()); } } measure->downloadedFile.clear(); } LeaveCriticalSection(&g_CriticalSection); } // Update the references std::vector<MeasureData*>::iterator i = g_Measures.begin(); std::wstring compareStr = L"["; compareStr += RmGetMeasureName(measure->rm); compareStr += L']'; for ( ; i != g_Measures.end(); ++i) { if (measure->skin == (*i)->skin && StringUtil::CaseInsensitiveFind((*i)->url, compareStr) != std::wstring::npos) { if ((*i)->stringIndex < rc) { const WCHAR* match = data + ovector[2 * (*i)->stringIndex]; int matchLen = ovector[2 * (*i)->stringIndex + 1] - ovector[2 * (*i)->stringIndex]; if (!(*i)->regExp.empty()) { // Change the index and parse the substring int index = (*i)->stringIndex; (*i)->stringIndex = (*i)->stringIndex2; ParseData((*i), (BYTE*)match, matchLen * 2, true); (*i)->stringIndex = index; } else { // Set the result EnterCriticalSection(&g_CriticalSection); // Substitude the [measure] with result (*i)->resultString = (*i)->url; (*i)->resultString.replace( StringUtil::CaseInsensitiveFind((*i)->resultString, compareStr), compareStr.size(), match, matchLen); DecodeReferences((*i)->resultString, (*i)->decodeCharacterReference); // Start download threads for the references if ((*i)->download) { // Start the download thread unsigned int id; HANDLE threadHandle = (HANDLE)_beginthreadex(nullptr, 0, NetworkDownloadThreadProc, (*i), 0, &id); if (threadHandle) { (*i)->dlThreadHandle = threadHandle; } } LeaveCriticalSection(&g_CriticalSection); } } else { RmLog((*i)->rm, LOG_WARNING, L"WebParser: Not enough substrings"); // Clear the old result EnterCriticalSection(&g_CriticalSection); (*i)->resultString.clear(); if ((*i)->download) { if ((*i)->downloadFile.empty()) // cache mode { if (!(*i)->downloadedFile.empty()) { // Delete old downloaded file DeleteFile((*i)->downloadedFile.c_str()); } } (*i)->downloadedFile.clear(); } LeaveCriticalSection(&g_CriticalSection); } } } } } else { // Matching failed: handle error cases RmLogF(measure->rm, LOG_ERROR, L"WebParser: RegExp matching error (%d)", rc); doErrorAction = true; EnterCriticalSection(&g_CriticalSection); measure->resultString = measure->errorString; // Update the references std::vector<MeasureData*>::iterator i = g_Measures.begin(); std::wstring compareStr = L"["; compareStr += RmGetMeasureName(measure->rm); compareStr += L']'; for ( ; i != g_Measures.end(); ++i) { if ((StringUtil::CaseInsensitiveFind((*i)->url, compareStr) != std::wstring::npos) && (measure->skin == (*i)->skin)) { (*i)->resultString = (*i)->errorString; } } LeaveCriticalSection(&g_CriticalSection); } // Release memory used for the compiled pattern pcre16_free(re); } else { // Compilation failed. RmLogF(measure->rm, LOG_ERROR, L"WebParser: RegExp error at offset %d: %S", erroffset, error); doErrorAction = true; } if (measure->download) { // Start the download thread unsigned int id; HANDLE threadHandle = (HANDLE)_beginthreadex(nullptr, 0, NetworkDownloadThreadProc, measure, 0, &id); if (threadHandle) { measure->dlThreadHandle = threadHandle; } } if (doErrorAction && !measure->onRegExpErrAction.empty()) { RmExecute(measure->skin, measure->onRegExpErrAction.c_str()); } else if (!measure->download && !measure->finishAction.empty()) { RmExecute(measure->skin, measure->finishAction.c_str()); } }
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { Measure* measure = (Measure*)data; ParentMeasure* parent = measure->parent; if (!parent) return; Player* player = parent->player; if (!player->IsInitialized()) { if (_wcsicmp(args, L"OpenPlayer") == 0 || _wcsicmp(args, L"TogglePlayer") == 0) { player->OpenPlayer(parent->playerPath); } } else if (_wcsicmp(args, L"Pause") == 0) { player->Pause(); } else if (_wcsicmp(args, L"Play") == 0) { player->Play(); } else if (_wcsicmp(args, L"PlayPause") == 0) { (player->GetState() != STATE_PLAYING) ? player->Play() : player->Pause(); } else if (_wcsicmp(args, L"Next") == 0) { player->Next(); } else if (_wcsicmp(args, L"Previous") == 0) { player->Previous(); } else if (_wcsicmp(args, L"Stop") == 0) { player->Stop(); } else if (_wcsicmp(args, L"OpenPlayer") == 0) { player->OpenPlayer(parent->playerPath); } else if (_wcsicmp(args, L"ClosePlayer") == 0 || _wcsicmp(args, L"TogglePlayer") == 0) { player->ClosePlayer(); } else { LPCWSTR arg = wcschr(args, L' '); if (arg) { ++arg; // Skip the space if (_wcsnicmp(args, L"SetPosition", 11) == 0) { int position = (_wtoi(arg) * (int)player->GetDuration()) / 100; if (arg[0] == L'+' || arg[0] == L'-') { position += player->GetPosition(); } player->SetPosition(position); } else if (_wcsnicmp(args, L"SetRating", 9) == 0) { int rating = _wtoi(arg); if (rating >= 0 && rating <= 5) { player->SetRating(rating); } } else if (_wcsnicmp(args, L"SetVolume", 9) == 0) { int volume = _wtoi(arg); if (arg[0] == L'+' || arg[0] == L'-') { // Relative to current volume volume += player->GetVolume(); } if (volume < 0) { volume = 0; } else if (volume > 100) { volume = 100; } player->SetVolume(volume);; } else if (_wcsnicmp(args, L"SetShuffle", 9) == 0) { int state = _wtoi(arg); if (state == -1) { player->SetShuffle(!player->GetShuffle()); } else if (state == 0 || state == 1) { player->SetShuffle(state != 0); } } else if (_wcsnicmp(args, L"SetRepeat", 9) == 0) { int state = _wtoi(arg); if (state == -1) { player->SetRepeat(!player->GetRepeat()); } else if (state == 0 || state == 1) { player->SetRepeat(state != 0); } } else { RmLog(LOG_WARNING, L"NowPlaying.dll: Unknown args"); } } else { RmLog(LOG_WARNING, L"NowPlaying.dll: Unknown args"); } } }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { Measure* measure = (Measure*)data; // Data is stored in two structs: Measure and ParentMeasure. ParentMeasure is created for measures // with PlayerName=someplayer. Measure is created for all measures and points to ParentMeasure as // referenced in PlayerName=[section]. // Read settings from the ini-file void* skin = RmGetSkin(rm); LPCWSTR str = RmReadString(rm, L"PlayerName", L"", FALSE); if (str[0] == L'[') { if (measure->parent) { // Don't let a measure measure change its parent } else { // PlayerName starts with [ so use referenced section ++str; size_t len = wcslen(str); if (len > 0 && str[len - 1] == L']') { --len; std::vector<ParentMeasure*>::iterator iter = g_ParentMeasures.begin(); for ( ; iter != g_ParentMeasures.end(); ++iter) { if (skin == (*iter)->skin && _wcsnicmp(str, (*iter)->ownerName, len) == 0) { // Use same ParentMeasure as referenced section measure->parent = (*iter); ++measure->parent->measureCount; break; } } if (!measure->parent) { // The referenced section doesn't exist std::wstring error = L"NowPlaying.dll: Invalid PlayerName="; error.append(str - 1, len + 2); error += L" in ["; error += RmGetMeasureName(rm); error += L"]"; RmLog(LOG_WARNING, error.c_str()); return; } } } } else { // ParentMeasure is created when PlayerName is an actual player (and not a reference) ParentMeasure* parent = measure->parent; Player* oldPlayer = nullptr; if (parent) { if (parent->data != data) { // Don't let a measure-only measure become a parent measure return; } oldPlayer = parent->player; } else { parent = new ParentMeasure; g_ParentMeasures.push_back(parent); parent->data = data; parent->skin = skin; parent->ownerName = RmGetMeasureName(rm); measure->parent = parent; } if (_wcsicmp(L"AIMP", str) == 0) { parent->player = PlayerAIMP::Create(); } else if (_wcsicmp(L"CAD", str) == 0) { parent->player = PlayerCAD::Create(); } else if (_wcsicmp(L"foobar2000", str) == 0) { HWND fooWindow = FindWindow(L"foo_rainmeter_class", nullptr); if (fooWindow) { const WCHAR* error = L"Your foobar2000 plugin is out of date.\n\nDo you want to update the plugin now?"; if (MessageBox(nullptr, error, L"Rainmeter", MB_YESNO | MB_ICONINFORMATION | MB_TOPMOST) == IDYES) { ShellExecute(nullptr, L"open", L"http://github.com/poiru/foo-cad#readme", nullptr, nullptr, SW_SHOWNORMAL); } } parent->player = PlayerCAD::Create(); } else if (_wcsicmp(L"iTunes", str) == 0) { parent->player = PlayerITunes::Create(); } else if (_wcsicmp(L"MediaMonkey", str) == 0) { parent->player = PlayerWinamp::Create(WA_MEDIAMONKEY); } else if (_wcsicmp(L"Spotify", str) == 0) { parent->player = PlayerSpotify::Create(); } else if (_wcsicmp(L"WinAmp", str) == 0) { parent->player = PlayerWinamp::Create(WA_WINAMP); } else if (_wcsicmp(L"WMP", str) == 0) { parent->player = PlayerWMP::Create(); } else { // Default to WLM parent->player = PlayerWLM::Create(); if (_wcsicmp(L"WLM", str) != 0) { std::wstring error = L"NowPlaying.dll: Invalid PlayerName="; error += str; error += L" in ["; error += parent->ownerName; error += L"]"; RmLog(LOG_ERROR, error.c_str()); } } parent->player->AddInstance(); parent->playerPath = RmReadString(rm, L"PlayerPath", L""); parent->trackChangeAction = RmReadString(rm, L"TrackChangeAction", L"", FALSE); parent->disableLeadingZero = RmReadInt(rm, L"DisableLeadingZero", 0) != 0; if (oldPlayer) { parent->player->SetMeasures(oldPlayer->GetMeasures()); // Remove instance here so that player doesn't have to reinitialize if PlayerName was // not changed. oldPlayer->RemoveInstance(); } } str = RmReadString(rm, L"PlayerType", L""); if (_wcsicmp(L"ARTIST", str) == 0) { measure->type = MEASURE_ARTIST; } else if (_wcsicmp(L"TITLE", str) == 0) { measure->type = MEASURE_TITLE; } else if (_wcsicmp(L"ALBUM", str) == 0) { measure->type = MEASURE_ALBUM; } else if (_wcsicmp(L"COVER", str) == 0) { measure->type = MEASURE_COVER; } else if (_wcsicmp(L"DURATION", str) == 0) { measure->type = MEASURE_DURATION; } else if (_wcsicmp(L"POSITION", str) == 0) { measure->type = MEASURE_POSITION; } else if (_wcsicmp(L"PROGRESS", str) == 0) { measure->type = MEASURE_PROGRESS; *maxValue = 100.0; } else if (_wcsicmp(L"RATING", str) == 0) { measure->type = MEASURE_RATING; *maxValue = 5.0; } else if (_wcsicmp(L"STATE", str) == 0) { measure->type = MEASURE_STATE; } else if (_wcsicmp(L"STATUS", str) == 0) { measure->type = MEASURE_STATUS; } else if (_wcsicmp(L"VOLUME", str) == 0) { measure->type = MEASURE_VOLUME; *maxValue = 100.0; } else if (_wcsicmp(L"SHUFFLE", str) == 0) { measure->type = MEASURE_SHUFFLE; } else if (_wcsicmp(L"REPEAT", str) == 0) { measure->type = MEASURE_REPEAT; } else if (_wcsicmp(L"LYRICS", str) == 0) { RmLog(LOG_WARNING, L"NowPlaying.dll: Using undocumented PlayerType=LYRICS!"); measure->type = MEASURE_LYRICS; } else if (_wcsicmp(L"FILE", str) == 0) { measure->type = MEASURE_FILE; } else if (_wcsicmp(L"NUMBER", str) == 0) { measure->type = MEASURE_NUMBER; } else if (_wcsicmp(L"YEAR", str) == 0) { measure->type = MEASURE_YEAR; } else { std::wstring error = L"NowPlaying.dll: Invalid PlayerType="; error += str; error += L" in ["; error += RmGetMeasureName(rm); error += L"]"; RmLog(LOG_WARNING, error.c_str()); } measure->parent->player->AddMeasure(measure->type); }
void RunCommand(Measure* measure) { std::unique_lock<std::recursive_mutex> lock(measure->mutex); std::wstring command = measure->program + L" " + measure->parameter; std::wstring folder = measure->folder; WORD state = measure->state; int timeout = measure->timeout; OutputType type = measure->outputType; lock.unlock(); std::wstring result = L""; bool error = false; HANDLE read = INVALID_HANDLE_VALUE; HANDLE write = INVALID_HANDLE_VALUE; /* Instead of trying to keep track of the following handles, use an array to make cleanup easier. HANDLE hOutputReadTmp; 0 HANDLE hOutputWrite; 1 HANDLE hInputWriteTmp; 2 HANDLE hInputRead; 3 HANDLE hErrorWrite; 4 */ HANDLE loadHandles[5]; for (int i = 0; i < sizeof(loadHandles) / sizeof(loadHandles[0]); ++i) { loadHandles[i] = INVALID_HANDLE_VALUE; } SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; HANDLE hProc = GetCurrentProcess(); // Create pipe for stdin, stdout, stderr if (CreatePipe(&loadHandles[0], &loadHandles[1], &sa, 0) && DuplicateHandle(hProc, loadHandles[1], hProc, &loadHandles[4], 0, TRUE, DUPLICATE_SAME_ACCESS) && CreatePipe(&loadHandles[3], &loadHandles[2], &sa, 0) && DuplicateHandle(hProc, loadHandles[0], hProc, &read, 0, FALSE, DUPLICATE_SAME_ACCESS) && DuplicateHandle(hProc, loadHandles[2], hProc, &write, 0, FALSE, DUPLICATE_SAME_ACCESS)) { BYTE buffer[MAX_LINE_LENGTH + 3]; DWORD bytesRead = 0; DWORD totalBytes = 0; DWORD bytesLeft = 0; DWORD exit = 0; PROCESS_INFORMATION pi; SecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); STARTUPINFO si; SecureZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = state; si.hStdOutput = loadHandles[1]; si.hStdInput = loadHandles[3]; si.hStdError = loadHandles[4]; if (CreateProcess(NULL, &command[0], NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, &folder[0], &si, &pi)) { // Store values inside measure for the "Close" or "Kill" command lock.lock(); measure->hProc = pi.hProcess; measure->dwPID = pi.dwProcessId; lock.unlock(); // Send command DWORD written; WriteFile(write, &command[0], MAX_LINE_LENGTH, &written, NULL); std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); // Read output of program (if any) while(true) { auto ReadFileAndSetResult = [&]() -> void { ReadFile(read, buffer, MAX_LINE_LENGTH, &bytesRead, NULL); // Triple "null" the buffer in case an odd number bytes is // converted to a multi-byte string. buffer[bytesRead] = '\0'; buffer[bytesRead + 1] = '\0'; buffer[bytesRead + 2] = '\0'; switch (type) { case OUTPUTTYPE_ANSI: result += StringUtil::Widen((LPCSTR)buffer); break; case OUTPUTTYPE_UTF8: result += StringUtil::WidenUTF8((LPCSTR)buffer); break; default: case OUTPUTTYPE_UTF16: result += (LPCWSTR)buffer; break; } SecureZeroMemory(buffer, sizeof(buffer)); // clear the buffer }; // Wait for a signal from the process (or timeout). // This reduced CPU usage significantly. WaitForSingleObject(pi.hThread, 1); // Check if there is any data to to read PeekNamedPipe(read, buffer, MAX_LINE_LENGTH, &bytesRead, &totalBytes, &bytesLeft); if (bytesRead != 0) { if (totalBytes > MAX_LINE_LENGTH) { while (bytesRead >= MAX_LINE_LENGTH) { ReadFileAndSetResult(); } } else { ReadFileAndSetResult(); } } // If a timeout is defined, attempt to terminate program and detach it from the plugin if ((timeout >= 0 && std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now() - start).count() > timeout)) { if (!TerminateApp(pi.hProcess, pi.dwProcessId, (state == SW_HIDE))) { lock.lock(); measure->value = 105.0f; RmLogF(measure->rm, LOG_ERROR, err_Terminate, measure->program.c_str()); // Could not terminate process (very rare!) error = true; lock.unlock(); } break; } // Check to see if the program is still running GetExitCodeProcess(pi.hProcess, &exit); if (exit != STILL_ACTIVE) break; } // Close process handles CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Update values in case the "Close" or "Kill" command is called lock.lock(); measure->hProc = INVALID_HANDLE_VALUE; measure->dwPID = 0; lock.unlock(); } else { lock.lock(); measure->value = 103.0f; RmLogF(measure->rm, LOG_ERROR, err_Process, measure->program.c_str()); // Cannot start process error = true; lock.unlock(); } } else { lock.lock(); measure->value = 106.0f; RmLog(measure->rm, LOG_ERROR, err_CreatePipe); // Cannot create pipe error = true; lock.unlock(); } // Close handles for (int i = 0; i < sizeof(loadHandles) / sizeof(loadHandles[0]); ++i) { if (loadHandles[i] != INVALID_HANDLE_VALUE) { CloseHandle(loadHandles[i]); } } CloseHandle(write); CloseHandle(read); // Remove any carriage returns result.erase(std::remove(result.begin(), result.end(), L'\r'), result.end()); HMODULE module = nullptr; lock.lock(); if (measure->threadActive) { measure->result = result; measure->result.shrink_to_fit(); if (!measure->outputFile.empty()) { std::wstring encoding = L"w+"; switch (type) { case OUTPUTTYPE_UTF8: { encoding.append(L", ccs=UTF-8"); break; } case OUTPUTTYPE_UTF16: { encoding.append(L", ccs=UTF-16LE"); break; } } FILE* file; if (_wfopen_s(&file, measure->outputFile.c_str(), encoding.c_str()) == 0) { fputws(result.c_str(), file); } else { measure->value = 104.0f; RmLogF(measure->rm, LOG_ERROR, err_SaveFile, measure->outputFile.c_str()); // Cannot save file error = true; } if (file) { fclose(file); } } // If no errors from the thread, // set number value of measure to 1 to indicate "Success". if (!error) { measure->value = 1.0f; } measure->threadActive = false; lock.unlock(); if (!measure->finishAction.empty()) { RmExecute(measure->skin, measure->finishAction.c_str()); } return; } lock.unlock(); delete measure; DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module); if (module) { // Decrement the ref count and possibly unload the module if this is the last instance. FreeLibraryAndExitThread(module, 0); } }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { Measure* measure = (Measure*)data; measure->rm = rm; //初始化 PlayerName LPCWSTR str = RmReadString(rm, L"PlayerName", L""); if (!_wcsicmp(L"KwMusic", str)) { measure->name = PLAYER_KUWO; measure->player = KwMusic::Create(); } else if (!_wcsicmp(L"KgMusic", str)) { measure->name = PLAYER_KUGOU; measure->player = KgMusic::Create(); } else if (!_wcsicmp(L"QQMusic", str)) { measure->name = PLAYER_QQ; measure->player = QQMusic::Create(); } else if (!_wcsicmp(L"BaiduMusic", str)) { measure->name = PLAYER_BAIDU; measure->player = BaiduMusic::Create(); } else { measure->name = PLAYER_KUWO; measure->player = KwMusic::Create(); wstring error = L"MusicPlayer.dll: Invalid PlayerName="; error += str; error += L" in ["; error += RmGetMeasureName(rm); error += L"]"; RmLog(LOG_WARNING, error.c_str()); } //初始化 PlayerType str = RmReadString(rm, L"PlayerType", L""); if (_wcsicmp(L"TITLE", str) == 0) { measure->type = MEASURE_TITLE; } else if (_wcsicmp(L"ARTIST", str) == 0) { measure->type = MEASURE_ARTIST; } else if (_wcsicmp(L"TRACK", str) == 0) { measure->type = MEASURE_TRACK; } else if (_wcsicmp(L"PLAYERPATH", str) == 0) { measure->type = MEASURE_PLAYERPATH; measure->playerpath = RmReadString(rm, L"PlayerPath", L""); } else if (_wcsicmp(L"STATUS", str) == 0) { measure->type = MEASURE_STATUS; } else if (_wcsicmp(L"COVER", str) == 0) { measure->type = MEASURE_COVER; switch (measure->name) { case PLAYER_KUGOU: case PLAYER_QQ: measure->player->m_RequireCover = true; } } else { std::wstring error = L"MusicPlayer.dll: Invalid PlayerType="; error += str; error += L" in ["; error += RmGetMeasureName(rm); error += L"]"; RmLog(LOG_WARNING, error.c_str()); } measure->trackChangeAction = RmReadString(rm, L"TrackChangeAction", L""); }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { MeasureData* measure = (MeasureData*)data; int defaultData = -1; LPCTSTR type = RmReadString(rm, L"SysInfoType", L""); if (_wcsicmp(L"COMPUTER_NAME", type) == 0) { measure->type = MEASURE_COMPUTER_NAME; } else if (_wcsicmp(L"USER_NAME", type) == 0) { measure->type = MEASURE_USER_NAME; } else if (_wcsicmp(L"WORK_AREA", type) == 0) { measure->type = MEASURE_WORK_AREA; } else if (_wcsicmp(L"SCREEN_SIZE", type) == 0) { measure->type = MEASURE_SCREEN_SIZE; } else if (_wcsicmp(L"RAS_STATUS", type) == 0) { measure->type = MEASURE_RAS_STATUS; } else if (_wcsicmp(L"OS_VERSION", type) == 0) { measure->type = MEASURE_OS_VERSION; } else if (_wcsicmp(L"OS_BITS", type) == 0) { measure->type = MEASURE_OS_BITS; } else if (_wcsicmp(L"ADAPTER_DESCRIPTION", type) == 0) { defaultData = 0; measure->type = MEASURE_ADAPTER_DESCRIPTION; } else if (_wcsicmp(L"NET_MASK", type) == 0) { defaultData = 0; measure->type = MEASURE_NET_MASK; } else if (_wcsicmp(L"IP_ADDRESS", type) == 0) { defaultData = 0; measure->type = MEASURE_IP_ADDRESS; } else if (_wcsicmp(L"GATEWAY_ADDRESS", type) == 0) { defaultData = 0; measure->type = MEASURE_GATEWAY_ADDRESS; } else if (_wcsicmp(L"HOST_NAME", type) == 0) { measure->type = MEASURE_HOST_NAME; } else if (_wcsicmp(L"DOMAIN_NAME", type) == 0) { measure->type = MEASURE_DOMAIN_NAME; } else if (_wcsicmp(L"DNS_SERVER", type) == 0) { measure->type = MEASURE_DNS_SERVER; } else if (_wcsicmp(L"WORK_AREA_TOP", type) == 0) { measure->type = MEASURE_WORK_AREA_TOP; } else if (_wcsicmp(L"WORK_AREA_LEFT", type) == 0) { measure->type = MEASURE_WORK_AREA_LEFT; } else if (_wcsicmp(L"WORK_AREA_WIDTH", type) == 0) { measure->type = MEASURE_WORK_AREA_WIDTH; } else if (_wcsicmp(L"WORK_AREA_HEIGHT", type) == 0) { measure->type = MEASURE_WORK_AREA_HEIGHT; } else if (_wcsicmp(L"SCREEN_WIDTH", type) == 0) { measure->type = MEASURE_SCREEN_WIDTH; } else if (_wcsicmp(L"SCREEN_HEIGHT", type) == 0) { measure->type = MEASURE_SCREEN_HEIGHT; } else if (_wcsicmp(L"NUM_MONITORS", type) == 0) { measure->type = MEASURE_NUM_MONITORS; } else if (_wcsicmp(L"VIRTUAL_SCREEN_TOP", type) == 0) { measure->type = MEASURE_VIRTUAL_SCREEN_TOP; } else if (_wcsicmp(L"VIRTUAL_SCREEN_LEFT", type) == 0) { measure->type = MEASURE_VIRTUAL_SCREEN_LEFT; } else if (_wcsicmp(L"VIRTUAL_SCREEN_WIDTH", type) == 0) { measure->type = MEASURE_VIRTUAL_SCREEN_WIDTH; } else if (_wcsicmp(L"VIRTUAL_SCREEN_HEIGHT", type) == 0) { measure->type = MEASURE_VIRTUAL_SCREEN_HEIGHT; } else { WCHAR buffer[256]; _snwprintf_s(buffer, _TRUNCATE, L"SysInfo.dll: SysInfoType=%s is not valid in [%s]", type, RmGetMeasureName(rm)); RmLog(LOG_ERROR, buffer); } measure->data = RmReadInt(rm, L"SysInfoData", defaultData); }
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { if (g_hClient == nullptr) return; MeasureData* measure = (MeasureData*)data; WCHAR buffer[128]; bool changed = false; int value = 0; auto logValueError = [&](const WCHAR* option) { _snwprintf_s(buffer, _TRUNCATE, L"WifiStatus.dll: %s=%i not valid", option, value); RmLog(LOG_ERROR, buffer); }; // Select a WLAN interface, default 0. value = RmReadInt(rm, L"WifiIntfID", 0); if (value >= (int)g_pIntfList->dwNumberOfItems) { logValueError(L"WifiIntfID"); value = 0; } g_pInterface = &g_pIntfList->InterfaceInfo[value]; // Select LIST style value = RmReadInt(rm, L"WifiListStyle", 0); if (value < 0 || value > 3) { logValueError(L"WifiListStyle"); value = 0; } measure->listStyle = value; // Set maxmimum number of list items value = RmReadInt(rm, L"WifiListLimit", 5); if (value <= 0) { logValueError(L"WifiListLimit"); value = 5; } measure->listMax = value; // Select type of measure MEASURETYPE infoType = UNKNOWN; LPCWSTR type = RmReadString(rm, L"WifiInfoType", L""); if (_wcsicmp(L"SSID", type) == 0) { infoType = SSID; } else if (_wcsicmp(L"TXRATE", type) == 0) { infoType = TXRATE; } else if (_wcsicmp(L"QUALITY", type) == 0) { infoType = QUALITY; } else if (_wcsicmp(L"ENCRYPTION", type) == 0) { infoType = ENCRYPTION; } else if (_wcsicmp(L"AUTH", type) == 0) { infoType = AUTH; } else if (_wcsicmp(L"LIST", type) == 0) { infoType = LIST; } else if (_wcsicmp(L"PHY", type) == 0) { infoType = PHY; } else { _snwprintf_s(buffer, _TRUNCATE, L"WifiStatus.dll: WifiInfoType=%s not valid", type); RmLog(LOG_ERROR, buffer); } if (infoType != measure->type) { changed = true; } measure->type = infoType; if (changed) { measure->statusString.clear(); switch (infoType) { case SSID: case ENCRYPTION: case AUTH: *maxValue = 0; break; case QUALITY: *maxValue = 100; break; } } }
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { ChildMeasure* child = (ChildMeasure*)data; ParentMeasure* parent = child->parent; // !CommandMeasure can only be used on the Parent measure. if (!parent || parent->ownerChild != child) return; // !CommandMeasure Clear if (_wcsicmp(args, L"Clear") == 0) { std::wstring currentData = parent->clipboard->GetIndex(0); // Clear contents of the Clipboard if (!parent->clipboard->DeleteClipboard()) { RmLog(LOG_ERROR, L"Clipboard.dll: Unable to delete clipboard"); } else { if (!currentData.empty()) { // Clear index 0 of ALL instances (if equal to current index 0) clearIndex(currentData); } } return; } else { // Check for commands with args. LPCWSTR arg = wcschr(args, L' '); if (arg) { // Skip the space ++arg; // !CommandMeasure ClearIndex n (where n represents an index) if (_wcsnicmp(args, L"ClearIndex", 10) == 0) { int index = _wtoi(arg); std::wstring currentData = parent->clipboard->GetIndex(index); if (!currentData.empty()) { // Index 0 represents the Windows Clipboard. If deleting this index, other parent measure need to be modified. if (index == 0) { parent->clipboard->ClearClipboard(); clearIndex(currentData); } else { if (!parent->clipboard->DeleteIndex(index)) { std::wstring error = L"Clipboard.dll: Unable to delete index \""; error += index; error += L'"'; RmLog(LOG_ERROR, error.c_str()); } } } return; } // !CommandMeasure "CopyIndex n" (where n represents an index) else if (_wcsnicmp(args, L"CopyIndex", 9) == 0) { LPCWSTR text = parent->clipboard->GetIndex(_wtoi(arg)); if (!parent->clipboard->SetClipboard(text)) { RmLog(LOG_ERROR, L"Clipboard.dll: Unable to set clipboard"); } return; } else { RmLog(LOG_ERROR, L"Clipboard.dll: Unknown args"); } } } return; }