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;
}
Beispiel #2
0
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=");
	}
}
Beispiel #4
0
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");
	}
}
Beispiel #5
0
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);
}
Beispiel #9
0
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");
}
Beispiel #12
0
/*
** 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");
	}
}
Beispiel #13
0
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=");
	}
}
Beispiel #14
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;
		RmLog(LOG_WARNING, L"CoreTemp.dll: Invalid CoreTempType");
	}

	return result;
}
Beispiel #15
0
// 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
}
Beispiel #16
0
/*
** 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");
		}
	}
}
Beispiel #17
0
	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;
	}
Beispiel #18
0
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);
	}
}
Beispiel #19
0
// 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");
	}
}
Beispiel #22
0
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);
}
Beispiel #23
0
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"");

}
Beispiel #28
0
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);
}
Beispiel #29
0
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;
}