CStdString CKeyboardStat::GetKeyName(int KeyID) { int keyid; CStdString keyname; keyname.clear(); // Get modifiers if (KeyID & CKey::MODIFIER_CTRL) keyname.append("ctrl-"); if (KeyID & CKey::MODIFIER_SHIFT) keyname.append("shift-"); if (KeyID & CKey::MODIFIER_ALT) keyname.append("alt-"); if (KeyID & CKey::MODIFIER_SUPER) keyname.append("win-"); // Now get the key name keyid = KeyID & 0x0FFF; if (keyid > NUM_KEYNAMES) keyname.AppendFormat("%i", keyid); else if (!keynames[keyid]) keyname.AppendFormat("%i", keyid); else keyname.append(keynames[keyid]); keyname.AppendFormat(" (%02x)", KeyID); return keyname; }
std::string CCECClient::GetConnectionInfo(void) { CStdString strLog; strLog.Format("libCEC version = %s, client version = %s, firmware version = %d", ToString((cec_server_version)m_configuration.serverVersion), ToString((cec_client_version)m_configuration.clientVersion), m_configuration.iFirmwareVersion); if (m_configuration.iFirmwareBuildDate != CEC_FW_BUILD_UNKNOWN) { time_t buildTime = (time_t)m_configuration.iFirmwareBuildDate; strLog.AppendFormat(", firmware build date: %s", asctime(gmtime(&buildTime))); strLog = strLog.Left((int)strLog.length() - 1); // strip \n added by asctime strLog.append(" +0000"); } // log the addresses that are being used if (!m_configuration.logicalAddresses.IsEmpty()) { strLog.append(", logical address(es) = "); CECDEVICEVEC devices; m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) strLog.AppendFormat("%s (%X) ", (*it)->GetLogicalAddressName(), (*it)->GetLogicalAddress()); } if (!CLibCEC::IsValidPhysicalAddress(m_configuration.iPhysicalAddress)) strLog.AppendFormat(", base device: %s (%X), HDMI port number: %d", ToString(m_configuration.baseDevice), m_configuration.baseDevice, m_configuration.iHDMIPort); else strLog.AppendFormat(", physical address: %04x", m_configuration.iPhysicalAddress); strLog.AppendFormat(", %s", LIB_CEC->GetLibInfo()); std::string strReturn(strLog.c_str()); return strReturn; }
bool CEpgDatabase::Delete(const CEpg &table, const CDateTime &start /* = NULL */, const CDateTime &end /* = NULL */) { /* invalid channel */ if (table.EpgID() <= 0) { CLog::Log(LOGERROR, "EpgDB - %s - invalid channel id: %d", __FUNCTION__, table.EpgID()); return false; } CLog::Log(LOGDEBUG, "EpgDB - %s - clearing the EPG '%d'", __FUNCTION__, table.EpgID()); CStdString strWhereClause; strWhereClause = FormatSQL("idEpg = %u", table.EpgID()); if (start != NULL) { time_t iStartTime; start.GetAsTime(iStartTime); strWhereClause.append(FormatSQL(" AND iStartTime < %u", iStartTime).c_str()); } if (end != NULL) { time_t iEndTime; end.GetAsTime(iEndTime); strWhereClause.append(FormatSQL(" AND iEndTime > %u", iEndTime).c_str()); } return DeleteValues("epgtags", strWhereClause); }
CStdString CKeyboardStat::GetKeyName(int KeyID) { int keyid; CStdString keyname; XBMCKEYTABLE keytable; keyname.clear(); // Get modifiers if (KeyID & CKey::MODIFIER_CTRL) keyname.append("ctrl-"); if (KeyID & CKey::MODIFIER_SHIFT) keyname.append("shift-"); if (KeyID & CKey::MODIFIER_ALT) keyname.append("alt-"); if (KeyID & CKey::MODIFIER_SUPER) keyname.append("win-"); // Now get the key name keyid = KeyID & 0xFF; if (KeyTableLookupVKeyName(keyid, &keytable)) keyname.append(keytable.keyname); else keyname.AppendFormat("%i", keyid); keyname.AppendFormat(" (%02x)", KeyID); return keyname; }
CStdString CSysInfo::GetUAWindowsVersion() { OSVERSIONINFOEX osvi = {}; osvi.dwOSVersionInfoSize = sizeof(osvi); CStdString strVersion = "Windows NT"; if (GetVersionEx((OSVERSIONINFO *)&osvi)) { strVersion.AppendFormat(" %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } SYSTEM_INFO si = {}; GetSystemInfo(&si); BOOL bIsWow = FALSE; if (IsWow64Process(GetCurrentProcess(), &bIsWow)) { if (bIsWow) { strVersion.append(";WOW64"); GetNativeSystemInfo(&si); // different function to read the info under Wow } } if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) strVersion.append(";Win64;x64"); else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) strVersion.append(";Win64;IA64"); return strVersion; }
void FormatWindowsError(int iErrorCode, CStdString &strMessage) { if (iErrorCode != ERROR_SUCCESS) { char strAddMessage[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, iErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), strAddMessage, 1024, NULL); strMessage.append(": "); strMessage.append(strAddMessage); } }
// curl calls this routine to debug extern "C" int debug_callback(CURL_HANDLE *handle, curl_infotype info, char *output, size_t size, void *data) { /* 歌方: 1、 卦指: 1、 傍苧: 1、 */ if (info == CURLINFO_DATA_IN || info == CURLINFO_DATA_OUT) return 0; // Only shown cURL debug into with loglevel DEBUG_SAMBA or higher if( g_advancedSettings.m_logLevel < LOG_LEVEL_DEBUG_SAMBA ) return 0; CStdString strLine; strLine.append(output, size); std::vector<CStdString> vecLines; CUtil::Tokenize(strLine, vecLines, "\r\n"); std::vector<CStdString>::const_iterator it = vecLines.begin(); while (it != vecLines.end()) { CLog::Log(LOGDEBUG, "Curl::Debug %s", (*it).c_str()); it++; } return 0; }
// curl calls this routine to debug extern "C" int debug_callback(CURL_HANDLE *handle, curl_infotype info, char *output, size_t size, void *data) { if (info == CURLINFO_DATA_IN || info == CURLINFO_DATA_OUT) return 0; if ((g_advancedSettings.m_extraLogLevels & LOGCURL) == 0) return 0; CStdString strLine; strLine.append(output, size); std::vector<CStdString> vecLines; CUtil::Tokenize(strLine, vecLines, "\r\n"); std::vector<CStdString>::const_iterator it = vecLines.begin(); char *infotype; switch(info) { case CURLINFO_TEXT : infotype = (char *) "TEXT: "; break; case CURLINFO_HEADER_IN : infotype = (char *) "HEADER_IN: "; break; case CURLINFO_HEADER_OUT : infotype = (char *) "HEADER_OUT: "; break; case CURLINFO_SSL_DATA_IN : infotype = (char *) "SSL_DATA_IN: "; break; case CURLINFO_SSL_DATA_OUT : infotype = (char *) "SSL_DATA_OUT: "; break; case CURLINFO_END : infotype = (char *) "END: "; break; default : infotype = (char *) ""; break; } while (it != vecLines.end()) { CLog::Log(LOGDEBUG, "Curl::Debug - %s%s", infotype, (*it).c_str()); it++; } return 0; }
bool CFileCurl::ReadData(CStdString& strHTML) { /* 歌方: 1、 卦指: 1、 傍苧: 1、 */ int size_read = 0; int data_size = 0; strHTML = ""; char buffer[16384]; while( (size_read = Read(buffer, sizeof(buffer)-1) ) > 0 ) { buffer[size_read] = 0; strHTML.append(buffer, size_read); data_size += size_read; } if (m_state->m_cancelled) return false; return true; }
bool CAFPDirectory::ResolveSymlink( const CStdString &dirName, const CStdString &fileName, struct stat *stat, CURL &resolvedUrl) { CSingleLock lock(gAfpConnection); int ret = 0; bool retVal = true; char resolvedLink[MAX_PATH]; CStdString fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath += fileName; CPasswordManager::GetInstance().AuthenticateURL(resolvedUrl); resolvedUrl.SetProtocol("afp"); resolvedUrl.SetHostName(gAfpConnection.GetConnectedIp()); ret = gAfpConnection.GetImpl()->afp_wrap_readlink(gAfpConnection.GetVolume(), fullpath.c_str(), resolvedLink, MAX_PATH); if(ret == 0) { fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(resolvedLink); if(resolvedLink[0] == '/') { //use the special stat function for using an extra context //because we are inside of a dir traversation //and just can't change the global nfs context here //without destroying something... fullpath = resolvedLink; fullpath = fullpath.Right(fullpath.length()-1); resolvedUrl.SetFileName(fullpath); ret = gAfpConnection.stat(resolvedUrl, stat); if(ret < 0) { URIUtils::AddSlashAtEnd(fullpath); resolvedUrl.SetFileName(fullpath); ret = gAfpConnection.stat(resolvedUrl, stat); } } else { ret = gAfpConnection.GetImpl()->afp_wrap_getattr(gAfpConnection.GetVolume(), fullpath.c_str(), stat); resolvedUrl.SetFileName(gAfpConnection.GetUrl()->volumename + fullpath); } if (ret != 0) { CLog::Log(LOGERROR, "AFP: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), strerror(errno)); retVal = false;; } } else { CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), strerror(errno)); retVal = false; } return retVal; }
bool ReadFileContents(CStdString const &strFileName, CStdString &strContent) { void* fileHandle = XBMC->OpenFile(strFileName.c_str(), 0); if (fileHandle) { char buffer[1024]; while (XBMC->ReadFileString(fileHandle, buffer, 1024)) strContent.append(buffer); XBMC->CloseFile(fileHandle); return true; } return false; }
bool CEpgDatabase::Delete(const CEpg &table, const time_t start /* = 0 */, const time_t end /* = 0 */) { /* invalid channel */ if (table.EpgID() <= 0) { CLog::Log(LOGERROR, "EpgDB - %s - invalid channel id: %d", __FUNCTION__, table.EpgID()); return false; } CStdString strWhereClause; strWhereClause = FormatSQL("idEpg = %u", table.EpgID()); if (start != 0) strWhereClause.append(FormatSQL(" AND iStartTime >= %u", start).c_str()); if (end != 0) strWhereClause.append(FormatSQL(" AND iEndTime <= %u", end).c_str()); CSingleLock lock(m_critSection); return DeleteValues("epgtags", strWhereClause); }
bool CFileCurl::ReadFile(const CStdString &fileName, CStdString &out) { XFILE::CFile file; if (file.Open(fileName)) { char buffer[16384]; unsigned int size_read; while( (size_read = file.Read(buffer, sizeof(buffer)) ) > 0 ) out.append(buffer, size_read); file.Close(); return true; } return false; }
bool CPVRDatabase::EraseEpgForChannel(const CPVRChannel &channel, const CDateTime &start /* = NULL */, const CDateTime &end /* = NULL */) { /* invalid channel */ if (channel.ChannelID() <= 0) { CLog::Log(LOGERROR, "PVRDB - %s - invalid channel id: %li", __FUNCTION__, channel.ChannelID()); return false; } CLog::Log(LOGDEBUG, "PVRDB - %s - clearing the EPG for channel '%s'", __FUNCTION__, channel.ChannelName().c_str()); CStdString strWhereClause; strWhereClause = FormatSQL("ChannelId = %u", channel.ChannelID()); if (start != NULL) strWhereClause.append(FormatSQL(" AND StartTime < %u", start.GetAsDBDateTime().c_str()).c_str()); if (end != NULL) strWhereClause.append(FormatSQL(" AND EndTime > %u", end.GetAsDBDateTime().c_str()).c_str()); return DeleteValues("EpgData", strWhereClause); }
//Receive until error or \n bool Socket::ReadResponses(int &code, vector<CStdString> &lines) { int result; char buffer[4096]; // this buff size has to be known in server code = 0; bool readComplete = false; CStdString bigString = ""; do { result = recv(_sd, buffer, sizeof(buffer) - 1, 0); if (result < 0) // if result is negative, the socket is bad { #ifdef TARGET_WINDOWS int errorCode = WSAGetLastError(); XBMC->Log(LOG_DEBUG, "ReadResponse ERROR - recv failed, Err: %d", errorCode); #else XBMC->Log(LOG_DEBUG, "ReadResponse ERROR - recv failed"); #endif code = 1; _sd = INVALID_SOCKET; return false; } if (result > 0) // if we got data from the server in this last pass { buffer[result] = 0; // insert end of string marker bigString.append(buffer); // accumulate all the reads } } while (result > 0); // keep reading until result returns '0', meaning server is done sending reponses if (EndsWith(bigString, "<EOF>")) { readComplete = true; // all server data has benn read lines = split(bigString, "<EOL>", true); // split each reponse by <EOL> delimiters lines.erase(lines.end() - 1); // erase <EOF> at end } else { XBMC->Log(LOG_DEBUG, "ReadResponse ERROR - <EOF> in read reponses not found"); _sd = INVALID_SOCKET; } return readComplete; }
// curl calls this routine to debug extern "C" int debug_callback(CURL_HANDLE *handle, curl_infotype info, char *output, size_t size, void *data) { if (info == CURLINFO_DATA_IN || info == CURLINFO_DATA_OUT) return 0; CStdString strLine; strLine.append(output, size); std::vector<CStdString> vecLines; CUtil::Tokenize(strLine, vecLines, "\r\n"); std::vector<CStdString>::const_iterator it = vecLines.begin(); while (it != vecLines.end()) { CLog::Log(LOGDEBUG, "Curl::Debug %s", (*it).c_str()); it++; } return 0; }
void CWIN32Util::ExtendDllPath() { CStdString strEnv; CStdStringArray vecEnv; strEnv = CEnvironment::getenv("PATH"); if (strEnv.IsEmpty()) CLog::Log(LOGWARNING, "Can get system env PATH or PATH is empty"); StringUtils::SplitString(DLL_ENV_PATH, ";", vecEnv); for (int i=0; i<(int)vecEnv.size(); ++i) strEnv.append(";" + CSpecialProtocol::TranslatePath(vecEnv[i])); if (CEnvironment::setenv("PATH", strEnv) == 0) CLog::Log(LOGDEBUG,"Setting system env PATH to %S",strEnv.c_str()); else CLog::Log(LOGDEBUG,"Can't set system env PATH to %S",strEnv.c_str()); }
bool CFileCurl::ReadData(CStdString& strHTML) { int size_read = 0; int data_size = 0; strHTML = ""; char buffer[16384]; while( (size_read = Read(buffer, sizeof(buffer)) ) > 0 ) { strHTML.append(buffer, size_read); data_size += size_read; } if (m_state->m_fileSize > 0 && m_state->m_fileSize != data_size) { CLog::Log(LOGDEBUG,"%s - not all data retrieved! (%d from %"PRId64"). aborting.", __FUNCTION__, data_size, m_state->m_fileSize); return false; } if (m_state->m_cancelled) return false; return true; }
void XLCDproc::SetLine(int iLine, const CStdString& strLine) { if (m_bStop || m_sockfd == -1) return; if (iLine < 0 || iLine >= (int)m_iRows) return; CStdString strLineLong = strLine; strLineLong.Trim(); StringToLCDCharSet(strLineLong); //make string fit the display if it's smaller than the width if (strLineLong.size() < m_iColumns) strLineLong.append(m_iColumns - strLineLong.size(), ' '); //else if the string doesn't fit the display, lcdproc will scroll it, so we need a space else if (strLineLong.size() > m_iColumns) strLineLong += " "; if (strLineLong != m_strLine[iLine]) { CStdString cmd; int ln = iLine + 1; if (g_advancedSettings.m_lcdScrolldelay != 0) cmd.Format("widget_set xbmc line%i 1 %i %i %i m %i \"%s\"\n", ln, ln, m_iColumns, ln, g_advancedSettings.m_lcdScrolldelay, strLineLong.c_str()); else cmd.Format("widget_set xbmc line%i 1 %i \"%s\"\n", ln, ln, strLineLong.c_str()); if (write(m_sockfd, cmd.c_str(), cmd.size()) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to write to socket", __FUNCTION__); CloseSocket(); return; } m_bUpdate[iLine] = true; m_strLine[iLine] = strLineLong; m_event.Set(); } }
void XLCDproc::SetBackLight(int iLight) { if (m_sockfd == -1) return; //Build command CStdString cmd; if (iLight == 0) { m_bStop = true; cmd = "screen_set xbmc -backlight off\n"; cmd.append("widget_del xbmc line1\n"); cmd.append("widget_del xbmc line2\n"); cmd.append("widget_del xbmc line3\n"); cmd.append("widget_del xbmc line4\n"); for(int i=0; i<4; i++) m_strLine[i] = ""; } else if (iLight > 0) { m_bStop = false; cmd = "screen_set xbmc -backlight on\n"; if (g_advancedSettings.m_lcdScrolldelay != 0) { cmd.append("widget_add xbmc line1 scroller\n"); cmd.append("widget_add xbmc line2 scroller\n"); cmd.append("widget_add xbmc line3 scroller\n"); cmd.append("widget_add xbmc line4 scroller\n"); } else { cmd.append("widget_add xbmc line1 string\n"); cmd.append("widget_add xbmc line2 string\n"); cmd.append("widget_add xbmc line3 string\n"); cmd.append("widget_add xbmc line4 string\n"); } } //Send to server if (write(m_sockfd,cmd.c_str(),cmd.size()) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to write to socket", __FUNCTION__); CloseSocket(); } }
CStdString ReplaceFileExtension(CStdString filePath, LPCTSTR newExtension) { if(filePath.IsEmpty() && (0 ==_tcslen(newExtension))) return _T(""); CStdString sFileWithNewExtension(_T("")); CStdString sExtensionToUse; if(_T('.') != newExtension[0]) sExtensionToUse = _T("."); sExtensionToUse.append(newExtension); int iExtensionPosition = filePath.ReverseFind(_T('.')); if(0 < iExtensionPosition) sFileWithNewExtension = filePath.Left(iExtensionPosition); else sFileWithNewExtension = filePath; sFileWithNewExtension += sExtensionToUse; return sFileWithNewExtension; }
CStdString CDatabase::GetSingleValue(const CStdString &strTable, const CStdString &strColumn, const CStdString &strWhereClause /* = CStdString() */, const CStdString &strOrderBy /* = CStdString() */) { CStdString strReturn; try { if (NULL == m_pDB.get()) return strReturn; if (NULL == m_pDS.get()) return strReturn; CStdString strQueryBase = "SELECT %s FROM %s"; if (!strWhereClause.IsEmpty()) strQueryBase.AppendFormat(" WHERE %s", strWhereClause.c_str()); if (!strOrderBy.IsEmpty()) strQueryBase.AppendFormat(" ORDER BY %s", strOrderBy.c_str()); strQueryBase.append(" LIMIT 1"); CStdString strQuery = PrepareSQL(strQueryBase, strColumn.c_str(), strTable.c_str()); if (!m_pDS->query(strQuery.c_str())) return strReturn; if (m_pDS->num_rows() > 0) { strReturn = m_pDS->fv(0).get_asString(); } m_pDS->close(); } catch(...) { CLog::Log(LOGERROR, "%s - failed to get value '%s' from table '%s'", __FUNCTION__, strColumn.c_str(), strTable.c_str()); } return strReturn; }
bool CNFSDirectory::ResolveSymlink( const CStdString &dirName, struct nfsdirent *dirent, CURL &resolvedUrl) { CSingleLock lock(gNfsConnection); int ret = 0; bool retVal = true; CStdString fullpath = dirName; char resolvedLink[MAX_PATH]; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(dirent->name); resolvedUrl.Reset(); resolvedUrl.SetPort(2049); resolvedUrl.SetProtocol("nfs"); resolvedUrl.SetHostName(gNfsConnection.GetConnectedIp()); ret = gNfsConnection.GetImpl()->nfs_readlink(gNfsConnection.GetNfsContext(), fullpath.c_str(), resolvedLink, MAX_PATH); if(ret == 0) { struct stat tmpBuffer = {0}; fullpath = dirName; URIUtils::AddSlashAtEnd(fullpath); fullpath.append(resolvedLink); //special case - if link target is absolute it could be even another export //intervolume symlinks baby ... if(resolvedLink[0] == '/') { //use the special stat function for using an extra context //because we are inside of a dir traversation //and just can't change the global nfs context here //without destroying something... fullpath = resolvedLink; resolvedUrl.SetFileName(fullpath); ret = gNfsConnection.stat(resolvedUrl, &tmpBuffer); } else { ret = gNfsConnection.GetImpl()->nfs_stat(gNfsConnection.GetNfsContext(), fullpath.c_str(), &tmpBuffer); resolvedUrl.SetFileName(gNfsConnection.GetConnectedExport() + fullpath); } if (ret != 0) { CLog::Log(LOGERROR, "NFS: Failed to stat(%s) on link resolve %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false;; } else { dirent->inode = tmpBuffer.st_ino; dirent->mode = tmpBuffer.st_mode; dirent->size = tmpBuffer.st_size; dirent->atime.tv_sec = tmpBuffer.st_atime; dirent->mtime.tv_sec = tmpBuffer.st_mtime; dirent->ctime.tv_sec = tmpBuffer.st_ctime; //map stat mode to nf3type if(S_ISBLK(tmpBuffer.st_mode)){ dirent->type = NF3BLK; } else if(S_ISCHR(tmpBuffer.st_mode)){ dirent->type = NF3CHR; } else if(S_ISDIR(tmpBuffer.st_mode)){ dirent->type = NF3DIR; } else if(S_ISFIFO(tmpBuffer.st_mode)){ dirent->type = NF3FIFO; } else if(S_ISREG(tmpBuffer.st_mode)){ dirent->type = NF3REG; } else if(S_ISLNK(tmpBuffer.st_mode)){ dirent->type = NF3LNK; } else if(S_ISSOCK(tmpBuffer.st_mode)){ dirent->type = NF3SOCK; } } } else { CLog::Log(LOGERROR, "Failed to readlink(%s) %s\n", fullpath.c_str(), gNfsConnection.GetImpl()->nfs_get_error(gNfsConnection.GetNfsContext())); retVal = false; } return retVal; }
bool XLCDproc::Connect() { CloseSocket(); struct hostent *server; server = gethostbyname(g_advancedSettings.m_lcdHostName); if (server == NULL) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to resolve LCDd host.", __FUNCTION__); return false; } m_sockfd = socket(AF_INET, SOCK_STREAM, 0); if (m_sockfd == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to create socket.", __FUNCTION__); return false; } struct sockaddr_in serv_addr = {}; serv_addr.sin_family = AF_INET; memmove(&serv_addr.sin_addr, server->h_addr_list[0], server->h_length); //Connect to default LCDd port, hard coded for now. serv_addr.sin_port = htons(13666); if (connect(m_sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to connect to host, LCDd not running?", __FUNCTION__); return false; } // Start a new session CStdString hello; hello = "hello\n"; if (write(m_sockfd,hello.c_str(),hello.size()) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to write to socket", __FUNCTION__); return false; } // Receive LCDproc data to determine row and column information char reply[1024] = {}; if (read(m_sockfd,reply,sizeof(reply) - 1) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to read from socket", __FUNCTION__); return false; } unsigned int i=0; while ((strncmp("lcd",reply + i,3) != 0 ) && (i < (strlen(reply) - 5))) i++; if(sscanf(reply+i,"lcd wid %u hgt %u", &m_iColumns, &m_iRows)) CLog::Log(LOGDEBUG, "XLCDproc::%s - LCDproc data: Columns %i - Rows %i.", __FUNCTION__, m_iColumns, m_iRows); //Build command to setup screen CStdString cmd; cmd = "screen_add xbmc\n"; if (!g_advancedSettings.m_lcdHeartbeat) cmd.append("screen_set xbmc -heartbeat off\n"); if (g_advancedSettings.m_lcdScrolldelay != 0) { cmd.append("widget_add xbmc line1 scroller\n"); cmd.append("widget_add xbmc line2 scroller\n"); cmd.append("widget_add xbmc line3 scroller\n"); cmd.append("widget_add xbmc line4 scroller\n"); } else { cmd.append("widget_add xbmc line1 string\n"); cmd.append("widget_add xbmc line2 string\n"); cmd.append("widget_add xbmc line3 string\n"); cmd.append("widget_add xbmc line4 string\n"); } //Send to server if (write(m_sockfd,cmd.c_str(),cmd.size()) == -1) { CLog::Log(LOGERROR, "XLCDproc::%s - Unable to write to socket", __FUNCTION__); return false; } return true; }
void CExternalPlayer::Process() { SetName("CExternalPlayer"); CStdString mainFile = m_launchFilename; CStdString archiveContent = ""; if (m_args.find("{0}") == std::string::npos) { // Unwind archive names CURL url(m_launchFilename); CStdString protocol = url.GetProtocol(); if (protocol == "zip" || protocol == "rar"/* || protocol == "iso9660" ??*/) { mainFile = url.GetHostName(); archiveContent = url.GetFileName(); } if (protocol == "musicdb") mainFile = CFileMusicDatabase::TranslateUrl(url); } if (m_filenameReplacers.size() > 0) { for (unsigned int i = 0; i < m_filenameReplacers.size(); i++) { std::vector<CStdString> vecSplit; StringUtils::SplitString(m_filenameReplacers[i], " , ", vecSplit); // something is wrong, go to next substitution if (vecSplit.size() != 4) continue; CStdString strMatch = vecSplit[0]; strMatch.Replace(",,",","); bool bCaseless = vecSplit[3].Find('i') > -1; CRegExp regExp(bCaseless); if (!regExp.RegComp(strMatch.c_str())) { // invalid regexp - complain in logs CLog::Log(LOGERROR, "%s: Invalid RegExp:'%s'", __FUNCTION__, strMatch.c_str()); continue; } if (regExp.RegFind(mainFile) > -1) { CStdString strPat = vecSplit[1]; strPat.Replace(",,",","); if (!regExp.RegComp(strPat.c_str())) { // invalid regexp - complain in logs CLog::Log(LOGERROR, "%s: Invalid RegExp:'%s'", __FUNCTION__, strPat.c_str()); continue; } CStdString strRep = vecSplit[2]; strRep.Replace(",,",","); bool bGlobal = vecSplit[3].Find('g') > -1; bool bStop = vecSplit[3].Find('s') > -1; int iStart = 0; while ((iStart = regExp.RegFind(mainFile, iStart)) > -1) { int iLength = regExp.GetFindLen(); mainFile = mainFile.Left(iStart) + regExp.GetReplaceString(strRep.c_str()) + mainFile.Mid(iStart+iLength); if (!bGlobal) break; } CLog::Log(LOGINFO, "%s: File matched:'%s' (RE='%s',Rep='%s') new filename:'%s'.", __FUNCTION__, strMatch.c_str(), strPat.c_str(), strRep.c_str(), mainFile.c_str()); if (bStop) break; } } } CLog::Log(LOGNOTICE, "%s: Player : %s", __FUNCTION__, m_filename.c_str()); CLog::Log(LOGNOTICE, "%s: File : %s", __FUNCTION__, mainFile.c_str()); CLog::Log(LOGNOTICE, "%s: Content: %s", __FUNCTION__, archiveContent.c_str()); CLog::Log(LOGNOTICE, "%s: Args : %s", __FUNCTION__, m_args.c_str()); CLog::Log(LOGNOTICE, "%s: Start", __FUNCTION__); // make sure we surround the arguments with quotes where necessary CStdString strFName; CStdString strFArgs; #if defined(_WIN32) // W32 batch-file handline if (m_filename.Right(4) == ".bat" || m_filename.Right(4) == ".cmd") { // MSDN says you just need to do this, but cmd's handing of spaces and // quotes is soo broken it seems to work much better if you just omit // lpApplicationName and enclose the module in lpCommandLine in quotes //strFName = "cmd.exe"; //strFArgs = "/c "; } else #endif strFName = m_filename; strFArgs.append("\""); strFArgs.append(m_filename); strFArgs.append("\" "); strFArgs.append(m_args); int nReplaced = strFArgs.Replace("{0}", mainFile); if (!nReplaced) nReplaced = strFArgs.Replace("{1}", mainFile) + strFArgs.Replace("{2}", archiveContent); if (!nReplaced) { strFArgs.append(" \""); strFArgs.append(mainFile); strFArgs.append("\""); } int iActiveDevice = g_audioContext.GetActiveDevice(); if (iActiveDevice != CAudioContext::NONE) { CLog::Log(LOGNOTICE, "%s: Releasing audio device %d", __FUNCTION__, iActiveDevice); g_audioContext.SetActiveDevice(CAudioContext::NONE); } #if defined(_WIN32) if (m_warpcursor) { GetCursorPos(&m_ptCursorpos); int x = 0; int y = 0; switch (m_warpcursor) { case WARP_BOTTOM_RIGHT: x = GetSystemMetrics(SM_CXSCREEN); case WARP_BOTTOM_LEFT: y = GetSystemMetrics(SM_CYSCREEN); break; case WARP_TOP_RIGHT: x = GetSystemMetrics(SM_CXSCREEN); break; case WARP_CENTER: x = GetSystemMetrics(SM_CXSCREEN) / 2; y = GetSystemMetrics(SM_CYSCREEN) / 2; break; } CLog::Log(LOGNOTICE, "%s: Warping cursor to (%d,%d)", __FUNCTION__, x, y); SetCursorPos(x,y); } LONG currentStyle = GetWindowLong(g_hWnd, GWL_EXSTYLE); #endif if (m_hidexbmc && !m_islauncher) { CLog::Log(LOGNOTICE, "%s: Hiding XBMC window", __FUNCTION__); g_Windowing.Hide(); } #if defined(_WIN32) else if (currentStyle & WS_EX_TOPMOST) { CLog::Log(LOGNOTICE, "%s: Lowering XBMC window", __FUNCTION__); SetWindowPos(g_hWnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW); } CLog::Log(LOGDEBUG, "%s: Unlocking foreground window", __FUNCTION__); LockSetForegroundWindow(LSFW_UNLOCK); #endif m_playbackStartTime = XbmcThreads::SystemClockMillis(); BOOL ret = TRUE; #if defined(_WIN32) ret = ExecuteAppW32(strFName.c_str(),strFArgs.c_str()); #elif defined(_LINUX) ret = ExecuteAppLinux(strFArgs.c_str()); #endif int64_t elapsedMillis = XbmcThreads::SystemClockMillis() - m_playbackStartTime; if (ret && (m_islauncher || elapsedMillis < LAUNCHER_PROCESS_TIME)) { if (m_hidexbmc) { CLog::Log(LOGNOTICE, "%s: XBMC cannot stay hidden for a launcher process", __FUNCTION__); g_Windowing.Show(false); } { CSingleLock lock(g_graphicsContext); m_dialog = (CGUIDialogOK *)g_windowManager.GetWindow(WINDOW_DIALOG_OK); m_dialog->SetHeading(23100); m_dialog->SetLine(1, 23104); m_dialog->SetLine(2, 23105); m_dialog->SetLine(3, 23106); } if (!m_bAbortRequest) m_dialog->DoModal(); } m_bIsPlaying = false; CLog::Log(LOGNOTICE, "%s: Stop", __FUNCTION__); #if defined(_WIN32) g_Windowing.Restore(); if (currentStyle & WS_EX_TOPMOST) { CLog::Log(LOGNOTICE, "%s: Showing XBMC window TOPMOST", __FUNCTION__); SetWindowPos(g_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW); SetForegroundWindow(g_hWnd); } else #endif { CLog::Log(LOGNOTICE, "%s: Showing XBMC window", __FUNCTION__); g_Windowing.Show(); } #if defined(_WIN32) if (m_warpcursor) { m_xPos = 0; m_yPos = 0; if (&m_ptCursorpos != 0) { m_xPos = (m_ptCursorpos.x); m_yPos = (m_ptCursorpos.y); } CLog::Log(LOGNOTICE, "%s: Restoring cursor to (%d,%d)", __FUNCTION__, m_xPos, m_yPos); SetCursorPos(m_xPos,m_yPos); } #endif // We don't want to come back to an active screensaver g_application.ResetScreenSaver(); g_application.WakeUpScreenSaverAndDPMS(); if (iActiveDevice != CAudioContext::NONE) { CLog::Log(LOGNOTICE, "%s: Reclaiming audio device %d", __FUNCTION__, iActiveDevice); g_audioContext.SetActiveDevice(iActiveDevice); } if (!ret || (m_playOneStackItem && g_application.CurrentFileItem().IsStack())) m_callback.OnPlayBackStopped(); else m_callback.OnPlayBackEnded(); }
int CEpgDatabase::Get(CEpg *epg, const CDateTime &start /* = NULL */, const CDateTime &end /* = NULL */) { int iReturn = -1; CStdString strWhereClause; strWhereClause = FormatSQL("idEpg = %u", epg->EpgID()); if (start != NULL) { time_t iStartTime; start.GetAsTime(iStartTime); strWhereClause.append(FormatSQL(" AND iStartTime < %u", iStartTime).c_str()); } if (end != NULL) { time_t iEndTime; end.GetAsTime(iEndTime); strWhereClause.append(FormatSQL(" AND iEndTime > %u", iEndTime).c_str()); } CStdString strQuery; strQuery.Format("SELECT * FROM epgtags WHERE %s ORDER BY iStartTime ASC;", strWhereClause.c_str()); if (ResultQuery(strQuery)) { iReturn = 0; try { while (!m_pDS->eof()) { CEpgInfoTag newTag; time_t iStartTime, iEndTime, iFirstAired; iStartTime = (time_t) m_pDS->fv("iStartTime").get_asInt(); CDateTime startTime(iStartTime); newTag.m_startTime = startTime; iEndTime = (time_t) m_pDS->fv("iEndTime").get_asInt(); CDateTime endTime(iEndTime); newTag.m_endTime = endTime; iFirstAired = (time_t) m_pDS->fv("iFirstAired").get_asInt(); CDateTime firstAired(iFirstAired); newTag.m_firstAired = firstAired; newTag.m_iUniqueBroadcastID = m_pDS->fv("iBroadcastUid").get_asInt(); newTag.m_iBroadcastId = m_pDS->fv("idBroadcast").get_asInt(); newTag.m_strTitle = m_pDS->fv("sTitle").get_asString().c_str(); newTag.m_strPlotOutline = m_pDS->fv("sPlotOutline").get_asString().c_str(); newTag.m_strPlot = m_pDS->fv("sPlot").get_asString().c_str(); newTag.m_iGenreType = m_pDS->fv("iGenreType").get_asInt(); newTag.m_iGenreSubType = m_pDS->fv("iGenreSubType").get_asInt(); newTag.m_iParentalRating = m_pDS->fv("iParentalRating").get_asInt(); newTag.m_iStarRating = m_pDS->fv("iStarRating").get_asInt(); newTag.m_bNotify = m_pDS->fv("bNotify").get_asBool(); newTag.m_iEpisodeNum = m_pDS->fv("iEpisodeId").get_asInt(); newTag.m_iEpisodePart = m_pDS->fv("iEpisodePart").get_asInt(); newTag.m_strEpisodeName = m_pDS->fv("sEpisodeName").get_asString().c_str(); newTag.m_iSeriesNum = m_pDS->fv("iSeriesId").get_asInt(); epg->AddEntry(newTag); ++iReturn; m_pDS->next(); } m_pDS->close(); } catch (...) { CLog::Log(LOGERROR, "%s - couldn't load EPG data from the database", __FUNCTION__); } } return iReturn; }
bool CSFTPSession::GetDirectory(const CStdString &base, const CStdString &folder, CFileItemList &items) { if (m_connected) { sftp_dir dir = NULL; { CSingleLock lock(m_critSect); m_LastActive = CTimeUtils::GetTimeMS(); dir = sftp_opendir(m_sftp_session, CorrectPath(folder).c_str()); } if (dir) { bool read = true; while (read) { sftp_attributes attributes = NULL; { CSingleLock lock(m_critSect); read = sftp_dir_eof(dir) == 0; attributes = sftp_readdir(m_sftp_session, dir); } if (attributes && (attributes->name == NULL || strcmp(attributes->name, "..") == 0 || strcmp(attributes->name, ".") == 0)) continue; if (attributes) { CStdString localPath = folder; localPath.append(attributes->name); if (attributes->type == SSH_FILEXFER_TYPE_SYMLINK) { CSingleLock lock(m_critSect); sftp_attributes_free(attributes); char *realpath = sftp_readlink(m_sftp_session, CorrectPath(localPath).c_str()); if(realpath == NULL) continue; attributes = sftp_stat(m_sftp_session, realpath); #ifdef _MSC_VER // hack since api doesn't expose any method to free // the memory alloced here, we cheat and use a // function that does a standard free inside the library string_free((ssh_string)realpath); #else free(realpath); #endif if (attributes == NULL) continue; if (attributes && (attributes->name == NULL || strcmp(attributes->name, "..") == 0 || strcmp(attributes->name, ".") == 0)) continue; } CFileItemPtr pItem(new CFileItem); pItem->SetLabel(attributes->name); if (attributes->name[0] == '.') pItem->SetProperty("file:hidden", true); if (attributes->flags & SSH_FILEXFER_ATTR_ACMODTIME) pItem->m_dateTime = attributes->mtime; if (attributes->type & SSH_FILEXFER_TYPE_DIRECTORY) { localPath.append("/"); pItem->m_bIsFolder = true; } pItem->m_strPath = base; pItem->m_strPath += localPath; items.Add(pItem); { CSingleLock lock(m_critSect); sftp_attributes_free(attributes); } } else read = false; } { CSingleLock lock(m_critSect); sftp_closedir(dir); } return true; } } else CLog::Log(LOGERROR, "SFTPSession: Not connected, can't list directory"); return false; }
bool CWINSMBDirectory::GetDirectory(const CStdString& strPath1, CFileItemList &items) { WIN32_FIND_DATAW wfd; CStdString strPath=strPath1; CURL url(strPath); if(url.GetShareName().empty()) { LPNETRESOURCEW lpnr = NULL; bool ret; if(!url.GetHostName().empty()) { lpnr = (LPNETRESOURCEW) GlobalAlloc(GPTR, 16384); if(lpnr == NULL) return false; ConnectToShare(url); CStdString strHost = "\\\\" + url.GetHostName(); CStdStringW strHostW; g_charsetConverter.utf8ToW(strHost,strHostW); lpnr->lpRemoteName = (LPWSTR)strHostW.c_str(); m_bHost = true; ret = EnumerateFunc(lpnr, items); GlobalFree((HGLOBAL) lpnr); m_bHost = false; } else ret = EnumerateFunc(lpnr, items); return ret; } memset(&wfd, 0, sizeof(wfd)); //rebuild the URL CStdString strUNCShare = "\\\\" + url.GetHostName() + "\\" + url.GetFileName(); strUNCShare.Replace("/", "\\"); if(!URIUtils::HasSlashAtEnd(strUNCShare)) strUNCShare.append("\\"); CStdStringW strSearchMask; g_charsetConverter.utf8ToW(strUNCShare, strSearchMask, false); strSearchMask += "*"; FILETIME localTime; CAutoPtrFind hFind ( FindFirstFileW(strSearchMask.c_str(), &wfd)); // on error, check if path exists at all, this will return true if empty folder if (!hFind.isValid()) { DWORD ret = GetLastError(); if(ret == ERROR_INVALID_PASSWORD || ret == ERROR_LOGON_FAILURE || ret == ERROR_ACCESS_DENIED || ret == ERROR_INVALID_HANDLE) { if(ConnectToShare(url) == false) return false; hFind.attach(FindFirstFileW(strSearchMask.c_str(), &wfd)); } else return Exists(strPath1); } if (hFind.isValid()) { do { if (wfd.cFileName[0] != 0) { CStdString strLabel; g_charsetConverter.wToUTF8(wfd.cFileName,strLabel); if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) { if (strLabel != "." && strLabel != "..") { CFileItemPtr pItem(new CFileItem(strLabel)); CStdString path = URIUtils::AddFileToFolder(strPath, strLabel); URIUtils::AddSlashAtEnd(path); pItem->SetPath(path); pItem->m_bIsFolder = true; FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime); pItem->m_dateTime=localTime; if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) pItem->SetProperty("file:hidden", true); items.Add(pItem); } } else { CFileItemPtr pItem(new CFileItem(strLabel)); pItem->SetPath(URIUtils::AddFileToFolder(strPath, strLabel)); pItem->m_bIsFolder = false; pItem->m_dwSize = CUtil::ToInt64(wfd.nFileSizeHigh, wfd.nFileSizeLow); FileTimeToLocalFileTime(&wfd.ftLastWriteTime, &localTime); pItem->m_dateTime=localTime; if (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) pItem->SetProperty("file:hidden", true); items.Add(pItem); } } } while (FindNextFileW((HANDLE)hFind, &wfd)); } return true; }
bool CWINSMBDirectory::EnumerateFunc(LPNETRESOURCEW lpnr, CFileItemList &items) { DWORD dwResult, dwResultEnum; HANDLE hEnum; DWORD cbBuffer = 16384; // 16K is a good size LPNETRESOURCEW lpnrLocal; // pointer to enumerated structures DWORD cEntries = -1; // enumerate all possible entries // // Call the WNetOpenEnum function to begin the enumeration. // dwResult = WNetOpenEnumW( RESOURCE_GLOBALNET, // all network resources RESOURCETYPE_DISK, // all disk resources 0, // enumerate all resources lpnr, // NULL first time the function is called &hEnum); // handle to the resource if (dwResult != NO_ERROR) { CLog::Log(LOGERROR,"WnetOpenEnum failed with error %d", dwResult); if(dwResult == ERROR_EXTENDED_ERROR) { DWORD dwWNetResult, dwLastError; CHAR szDescription[256]; CHAR szProvider[256]; dwWNetResult = WNetGetLastError(&dwLastError, // error code (LPSTR) szDescription, // buffer for error description sizeof(szDescription), // size of error buffer (LPSTR) szProvider, // buffer for provider name sizeof(szProvider)); // size of name buffer if(dwWNetResult == NO_ERROR) CLog::Log(LOGERROR,"%s failed with code %ld; %s", szProvider, dwLastError, szDescription); } return false; } // // Call the GlobalAlloc function to allocate resources. // lpnrLocal = (LPNETRESOURCEW) GlobalAlloc(GPTR, cbBuffer); if (lpnrLocal == NULL) { CLog::Log(LOGERROR,"Can't allocate buffer %d", cbBuffer); return false; } do { // // Initialize the buffer. // ZeroMemory(lpnrLocal, cbBuffer); // // Call the WNetEnumResource function to continue // the enumeration. // dwResultEnum = WNetEnumResourceW( hEnum, // resource handle &cEntries, // defined locally as -1 lpnrLocal, // LPNETRESOURCE &cbBuffer); // buffer size // // If the call succeeds, loop through the structures. // if (dwResultEnum == NO_ERROR) { for (DWORD i = 0; i < cEntries; i++) { DWORD dwDisplayType = lpnrLocal[i].dwDisplayType; DWORD dwType = lpnrLocal[i].dwType; if((((dwDisplayType == RESOURCEDISPLAYTYPE_SERVER) && (m_bHost == false)) || ((dwDisplayType == RESOURCEDISPLAYTYPE_SHARE) && m_bHost)) && (dwType != RESOURCETYPE_PRINT)) { CStdString strurl = "smb:"; CStdStringW strRemoteNameW = lpnrLocal[i].lpRemoteName; CStdString strName,strRemoteName; g_charsetConverter.wToUTF8(strRemoteNameW,strRemoteName); CLog::Log(LOGDEBUG,"Found Server/Share: %s", strRemoteName.c_str()); strurl.append(strRemoteName); strurl.Replace("\\","/"); CURL rooturl(strurl); rooturl.SetFileName(""); if(!rooturl.GetShareName().empty()) strName = rooturl.GetShareName(); else strName = rooturl.GetHostName(); strName.Replace("\\",""); URIUtils::AddSlashAtEnd(strurl); CFileItemPtr pItem(new CFileItem(strName)); pItem->SetPath(strurl); pItem->m_bIsFolder = true; items.Add(pItem); } // If the NETRESOURCE structure represents a container resource, // call the EnumerateFunc function recursively. if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER)) EnumerateFunc(&lpnrLocal[i], items); } } // Process errors. // else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { CLog::Log(LOGERROR,"WNetEnumResource failed with error %d", dwResultEnum); break; } } // // End do. // while (dwResultEnum != ERROR_NO_MORE_ITEMS); // // Call the GlobalFree function to free the memory. // GlobalFree((HGLOBAL) lpnrLocal); // // Call WNetCloseEnum to end the enumeration. // dwResult = WNetCloseEnum(hEnum); if (dwResult != NO_ERROR) { // // Process errors. // CLog::Log(LOGERROR,"WNetCloseEnum failed with error %d", dwResult); return false; } return true; }
CStdString CSysInfo::GetKernelVersion() { #if defined (_LINUX) struct utsname un; if (uname(&un)==0) { CStdString strKernel; strKernel.Format("%s %s %s %s", un.sysname, un.release, un.version, un.machine); return strKernel; } return ""; #else OSVERSIONINFOEX osvi; SYSTEM_INFO si; ZeroMemory(&si, sizeof(SYSTEM_INFO)); ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); GetSystemInfo(&si); osvi.dwOSVersionInfoSize = sizeof(osvi); CStdString strKernel = "Windows "; if (GetVersionEx((OSVERSIONINFO *)&osvi)) { if ( osvi.dwMajorVersion == 6 ) { if (osvi.dwMinorVersion == 0) { if( osvi.wProductType == VER_NT_WORKSTATION ) strKernel.append("Vista"); else strKernel.append("Server 2008"); } else if (osvi.dwMinorVersion == 1) { if( osvi.wProductType == VER_NT_WORKSTATION ) strKernel.append("7"); else strKernel.append("Server 2008 R2"); } if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) strKernel.append(", 64-bit Native"); else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) { BOOL bIsWow = FALSE;; if(IsWow64Process(GetCurrentProcess(), &bIsWow)) { if (bIsWow) { GetNativeSystemInfo(&si); if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) strKernel.append(", 64-bit (WoW)"); } else { strKernel.append(", 32-bit"); } } else strKernel.append(", 32-bit"); } } else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) { if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) { strKernel.append("XP Professional x64 Edition"); } } else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { strKernel.append("XP "); if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) strKernel.append("Home Edition" ); else strKernel.append("Professional" ); } else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) { strKernel.append("2000"); } if( _tcslen(osvi.szCSDVersion) > 0 ) { strKernel.append(" "); strKernel.append(osvi.szCSDVersion); } CStdString strBuild; strBuild.Format(" build %d",osvi.dwBuildNumber); strKernel += strBuild; } return strKernel; #endif }