void LogInternal(int nLevel, ULONGLONG elapsed, LPCTSTR pszMessage) { // Add timestamp WCHAR buffer[128]; size_t len = _snwprintf_s(buffer, _TRUNCATE, L"%02llu:%02llu:%02llu.%03llu", elapsed / (1000 * 60 * 60), (elapsed / (1000 * 60)) % 60, (elapsed / 1000) % 60, elapsed % 1000); Rainmeter->AddAboutLogInfo(nLevel, buffer, pszMessage); #ifndef _DEBUG if (!Rainmeter->GetLogging()) return; #endif std::wstring message; switch (nLevel) { case LOG_ERROR: message = L"ERRO"; break; case LOG_WARNING: message = L"WARN"; break; case LOG_NOTICE: message = L"NOTE"; break; case LOG_DEBUG: message = L"DBUG"; break; } message += L" ("; message.append(buffer, len); message += L") "; message += pszMessage; message += L'\n'; #ifdef _DEBUG _RPT0(_CRT_WARN, ConvertToAscii(message.c_str()).c_str()); if (!Rainmeter->GetLogging()) return; #endif const WCHAR* logFile = Rainmeter->GetLogFile().c_str(); if (_waccess(logFile, 0) == -1) { // Disable logging if the file was deleted manually Rainmeter->StopLogging(); } else { FILE* file = _wfopen(logFile, L"a+, ccs=UTF-8"); if (file) { fputws(message.c_str(), file); fclose(file); } } }
void LuaManager::PushWide(lua_State* L, const WCHAR* str) { lua_pushstring(L, ConvertToAscii(str).c_str()); }
bool DialogInstall::ReadPackage() { const WCHAR* fileName = m_PackageFileName.c_str(); const WCHAR* fileExtension = PathFindExtension(fileName); if (_wcsicmp(fileExtension, L".rmskin") == 0) { // Check if the footer is present (for new .rmskin format) PackageFooter footer = {0}; FILE* file = _wfopen(fileName, L"rb"); __int64 fileSize = 0; if (file) { fseek(file, -(long)sizeof(footer), SEEK_END); fileSize = _ftelli64(file); fread(&footer, sizeof(footer), 1, file); fclose(file); } if (strcmp(footer.key, "RMSKIN") == 0) { m_PackageFormat = PackageFormat::New; if (footer.size != fileSize) { return false; } if (footer.flags) { m_BackupPackage = !(footer.flags & PackageFlag::Backup); } } } else if (_wcsicmp(fileExtension, L".zip") != 0) { return false; } m_PackageUnzFile = unzOpen(ConvertToAscii(fileName).c_str()); if (!m_PackageUnzFile) { return false; } WCHAR buffer[MAX_PATH]; // Get temporary file to extract the options file and header bitmap GetTempPath(MAX_PATH, buffer); GetTempFileName(buffer, L"dat", 0, buffer); std::wstring tempFile = buffer; const WCHAR* tempFileSz = tempFile.c_str(); // Helper to sets buffer with current file name auto getFileInfo = [&]()->bool { char cBuffer[MAX_PATH * 3]; unz_file_info ufi; if (unzGetCurrentFileInfo( m_PackageUnzFile, &ufi, cBuffer, _countof(cBuffer), nullptr, 0, nullptr, 0) == UNZ_OK) { const uLong ZIP_UTF8_FLAG = 1 << 11; const DWORD codePage = (ufi.flag & ZIP_UTF8_FLAG) ? CP_UTF8 : CP_ACP; MultiByteToWideChar(codePage, 0, cBuffer, strlen(cBuffer) + 1, buffer, MAX_PATH); while (WCHAR* pos = wcschr(buffer, L'/')) *pos = L'\\'; return true; } return false; }; // Loop through the contents of the archive until the settings file is found WCHAR* path; bool optionsFound = false; do { if (!getFileInfo()) { return false; } path = wcsrchr(buffer, L'\\'); if (!path) { path = buffer; } else { if (m_PackageFormat == PackageFormat::New) { // New package files must be in root of archive continue; } ++path; // Skip slash } if (_wcsicmp(path, m_PackageFormat == PackageFormat::New ? L"RMSKIN.ini" : L"Rainstaller.cfg") == 0) { if (ExtractCurrentFile(tempFile)) { optionsFound = ReadOptions(tempFileSz); DeleteFile(tempFileSz); } break; } } while (unzGoToNextFile(m_PackageUnzFile) == UNZ_OK); if (!optionsFound) { return false; } // Loop through the archive a second time and find included components unzGoToFirstFile(m_PackageUnzFile); m_PackageRoot.assign(buffer, path - buffer); const WCHAR* root = m_PackageRoot.c_str(); do { if (!getFileInfo()) { return false; } if (wcsncmp(buffer, root, m_PackageRoot.length()) != 0) { // Ignore everything that isn't in the root directory continue; } WCHAR* component = buffer + m_PackageRoot.length(); path = wcschr(component, L'\\'); if (path) { *path = L'\0'; ++path; } else { if (_wcsicmp(component, m_PackageFormat == PackageFormat::New ? L"RMSKIN.bmp" : L"Rainstaller.bmp") == 0) { if (!ExtractCurrentFile(tempFile)) { return false; } m_HeaderBitmap = (HBITMAP)LoadImage(nullptr, tempFileSz, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); DeleteFile(tempFileSz); } continue; } const WCHAR* pos = wcschr(path, L'\\'); const WCHAR* extension = PathFindExtension(pos ? pos : path); if (pos) { // Component with subfolders const std::wstring item(path, pos - path); const WCHAR* itemSz = item.c_str(); if (_wcsicmp(component, L"Skins") == 0 && !IsIgnoredSkin(itemSz)) { m_PackageSkins.insert(item); } else if (_wcsicmp(component, m_PackageFormat == PackageFormat::New ? L"Layouts" : L"Themes") == 0 && _wcsicmp(extension, m_PackageFormat == PackageFormat::New ? L".ini" : L".thm") == 0 && !IsIgnoredLayout(itemSz)) { m_PackageLayouts.insert(item); } else if (_wcsicmp(component, L"Addons") == 0 && m_PackageFormat == PackageFormat::Old && !IsIgnoredAddon(itemSz)) { m_PackageAddons.insert(item); } else if (_wcsicmp(component, L"Plugins") == 0 && _wcsicmp(itemSz, IsWin32Build() ? L"32bit" : L"64bit") == 0 && _wcsicmp(extension, L".dll") == 0 && !wcschr(pos + 1, L'\\')) { const std::wstring plugin(pos + 1); if (!IsIgnoredPlugin(plugin.c_str())) { m_PackagePlugins.insert(plugin); } } } else { // Component with subfiles const std::wstring item = path; const WCHAR* itemSz = item.c_str(); if (_wcsicmp(component, L"Fonts") == 0 && m_PackageFormat == PackageFormat::Old && _wcsicmp(extension, L".ttf") == 0) { m_PackageFonts.insert(item); } } } while (unzGoToNextFile(m_PackageUnzFile) == UNZ_OK); if (m_PackageSkins.empty()) { // Fonts can be installed only with skins m_PackageFonts.clear(); } return !(m_PackageSkins.empty() && m_PackageLayouts.empty() && m_PackageAddons.empty() && m_PackageFonts.empty() && m_PackagePlugins.empty()); }
/* ** Read the options specified in the ini file. ** */ void CMeasureScript::ReadOptions(CConfigParser& parser, const WCHAR* section) { CMeasure::ReadOptions(parser, section); std::wstring file = parser.ReadString(section, L"ScriptFile", L""); if (!file.empty()) { if (m_MeterWindow) { m_MeterWindow->MakePathAbsolute(file); } std::string scriptFile = ConvertToAscii(file.c_str()); if (!m_Initialized || strcmp(scriptFile.c_str(), m_ScriptFile.c_str()) != 0) { DeleteLuaScript(); lua_State* L = LuaManager::GetState(); m_ScriptFile = scriptFile; m_LuaScript = new LuaScript(m_ScriptFile.c_str()); if (m_LuaScript->IsInitialized()) { bool hasInitializeFunction = m_LuaScript->IsFunction(g_InitializeFunctionName); m_HasUpdateFunction = m_LuaScript->IsFunction(g_UpdateFunctionName); m_HasGetStringFunction = m_LuaScript->IsFunction(g_GetStringFunctionName); // For backwards compatbility if (m_HasGetStringFunction) { LogWithArgs(LOG_WARNING, L"Script: Using deprecated GetStringValue() in [%s]", m_Name.c_str()); } lua_rawgeti(L, LUA_GLOBALSINDEX, m_LuaScript->GetRef()); *(CMeterWindow**)lua_newuserdata(L, sizeof(CMeterWindow*)) = m_MeterWindow; lua_getglobal(L, "CMeterWindow"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SKIN"); *(CMeasure**)lua_newuserdata(L, sizeof(CMeasure*)) = this; lua_getglobal(L, "CMeasure"); lua_setmetatable(L, -2); lua_setfield(L, -2, "SELF"); // For backwards compatibility lua_getfield(L, -1, "PROPERTIES"); if (lua_isnil(L, -1) == 0) { lua_pushnil(L); // Look in the table for values to read from the section while (lua_next(L, -2)) { lua_pop(L, 1); const char* strKey = lua_tostring(L, -1); std::wstring wstrKey = ConvertToWide(strKey); const std::wstring& wstrValue = parser.ReadString(section, wstrKey.c_str(), L""); if (!wstrValue.empty()) { std::string strStrVal = ConvertToAscii(wstrValue.c_str()); const char* strValue = strStrVal.c_str(); lua_pushstring(L, strValue); lua_setfield(L, -3, strKey); } } } // Pop PROPERTIES table and our table lua_pop(L, 2); if (hasInitializeFunction) { m_LuaScript->RunFunction(g_InitializeFunctionName); } } else { DeleteLuaScript(); } } } else { LogWithArgs(LOG_ERROR, L"Script: File not valid in [%s]", m_Name.c_str()); DeleteLuaScript(); } }
/* ** Executes a custom bang. ** */ void CMeasureScript::Command(const std::wstring& command) { std::string str = ConvertToAscii(command.c_str()); m_LuaScript->RunString(str.c_str()); }
PLUGIN_EXPORT double Update(void* data) { MeasureData* measure = (MeasureData*)data; if (measure->files.empty()) { BYTE buffer[BUFFER_SIZE + 2]; buffer[BUFFER_SIZE] = 0; // Read the file FILE* file = _wfopen(measure->pathname.c_str(), L"r"); if (file) { // Check if the file is unicode or ascii fread(buffer, sizeof(WCHAR), 1, file); fseek(file, 0, SEEK_END); long size = ftell(file); if (size > 0) { // Go to a random place int pos = rand() % size; fseek(file, (pos / 2) * 2, SEEK_SET); measure->value.clear(); if (0xFEFF == *(WCHAR*)buffer) { // It's unicode WCHAR* wBuffer = (WCHAR*)buffer; // Read until we find the first separator WCHAR* sepPos1 = NULL; WCHAR* sepPos2 = NULL; do { size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); buffer[len] = 0; buffer[len + 1] = 0; sepPos1 = wcsstr(wBuffer, measure->separator.c_str()); if (sepPos1 == NULL) { // The separator wasn't found if (feof(file)) { // End of file reached -> read from start fseek(file, 2, SEEK_SET); len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); buffer[len] = 0; buffer[len + 1] = 0; sepPos1 = wBuffer; } // else continue reading } else { sepPos1 += measure->separator.size(); } } while (sepPos1 == NULL); // Find the second separator do { sepPos2 = wcsstr(sepPos1, measure->separator.c_str()); if (sepPos2 == NULL) { // The separator wasn't found if (feof(file)) { // End of file reached -> read the rest measure->value += sepPos1; break; } else { measure->value += sepPos1; // else continue reading size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); buffer[len] = 0; buffer[len + 1] = 0; sepPos1 = wBuffer; } } else { if (sepPos2) { *sepPos2 = 0; } // Read until we find the second separator measure->value += sepPos1; } } while (sepPos2 == NULL); } else { // It's ascii char* aBuffer = (char*)buffer; // Read until we find the first separator char* sepPos1 = NULL; char* sepPos2 = NULL; do { size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); aBuffer[len] = 0; sepPos1 = strstr(aBuffer, ConvertToAscii(measure->separator.c_str()).c_str()); if (sepPos1 == NULL) { // The separator wasn't found if (feof(file)) { // End of file reached -> read from start fseek(file, 0, SEEK_SET); len = fread(buffer, sizeof(char), BUFFER_SIZE, file); aBuffer[len] = 0; sepPos1 = aBuffer; } // else continue reading } else { sepPos1 += measure->separator.size(); } } while (sepPos1 == NULL); // Find the second separator do { sepPos2 = strstr(sepPos1, ConvertToAscii(measure->separator.c_str()).c_str()); if (sepPos2 == NULL) { // The separator wasn't found if (feof(file)) { // End of file reached -> read the rest measure->value += ConvertToWide(sepPos1); break; } else { measure->value += ConvertToWide(sepPos1); // else continue reading size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); aBuffer[len] = 0; sepPos1 = aBuffer; } } else { if (sepPos2) { *sepPos2 = 0; } // Read until we find the second separator measure->value += ConvertToWide(sepPos1); } } while (sepPos2 == NULL); } } fclose(file); } } else { // Select the filename measure->value = measure->files[rand() % measure->files.size()]; } return 0; }
std::string Toolbox::ConvertToUtf8(const std::string& source, const Encoding sourceEncoding) { const char* encoding; // http://bradleyross.users.sourceforge.net/docs/dicom/doc/src-html/org/dcm4che2/data/SpecificCharacterSet.html switch (sourceEncoding) { case Encoding_Utf8: // Already in UTF-8: No conversion is required return source; case Encoding_Ascii: return ConvertToAscii(source); case Encoding_Latin1: encoding = "ISO-8859-1"; break; case Encoding_Latin2: encoding = "ISO-8859-2"; break; case Encoding_Latin3: encoding = "ISO-8859-3"; break; case Encoding_Latin4: encoding = "ISO-8859-4"; break; case Encoding_Latin5: encoding = "ISO-8859-9"; break; case Encoding_Cyrillic: encoding = "ISO-8859-5"; break; case Encoding_Windows1251: encoding = "WINDOWS-1251"; break; case Encoding_Arabic: encoding = "ISO-8859-6"; break; case Encoding_Greek: encoding = "ISO-8859-7"; break; case Encoding_Hebrew: encoding = "ISO-8859-8"; break; case Encoding_Japanese: encoding = "SHIFT-JIS"; break; case Encoding_Chinese: encoding = "GB18030"; break; case Encoding_Thai: encoding = "TIS620.2533-0"; break; default: throw OrthancException(ErrorCode_NotImplemented); } try { return boost::locale::conv::to_utf<char>(source, encoding); } catch (std::runtime_error&) { // Bad input string or bad encoding return ConvertToAscii(source); } }