std::wstring CWIN32Util::ConvertPathToWin32Form(const CURL& url) { assert(url.GetProtocol().empty() || url.IsProtocol("smb")); if (url.GetFileName().empty()) return std::wstring(); // empty string if (url.GetProtocol().empty()) { std::wstring result; if (g_charsetConverter.utf8ToW("\\\\?\\" + URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(url.GetFileName(), '\\'), '\\'), result, false, false, true)) return result; } else if (url.IsProtocol("smb")) { if (url.GetHostName().empty()) return std::wstring(); // empty string std::wstring result; if (g_charsetConverter.utf8ToW("\\\\?\\UNC\\" + URIUtils::CanonicalizePath(URIUtils::FixSlashesAndDups(url.GetHostName() + '\\' + url.GetFileName(), '\\'), '\\'), result, false, false, true)) return result; } else return std::wstring(); // unsupported protocol, return empty string CLog::Log(LOGERROR, "%s: Error converting path \"%s\" to Win32 form", __FUNCTION__, url.Get().c_str()); return std::wstring(); // empty string }
bool URIUtils::IsInternetStream(const CURL& url, bool bStrictCheck /* = false */) { if (url.GetProtocol().empty()) return false; // there's nothing to stop internet streams from being stacked if (url.IsProtocol("stack")) return IsInternetStream(CStackDirectory::GetFirstStackedFile(url.Get())); // Special case these if (url.IsProtocol("ftp") || url.IsProtocol("ftps") || url.IsProtocol("dav") || url.IsProtocol("davs") || url.IsProtocol("sftp")) return bStrictCheck; std::string protocol = url.GetTranslatedProtocol(); if (CURL::IsProtocolEqual(protocol, "http") || CURL::IsProtocolEqual(protocol, "https") || CURL::IsProtocolEqual(protocol, "tcp") || CURL::IsProtocolEqual(protocol, "udp") || CURL::IsProtocolEqual(protocol, "rtp") || CURL::IsProtocolEqual(protocol, "sdp") || CURL::IsProtocolEqual(protocol, "mms") || CURL::IsProtocolEqual(protocol, "mmst") || CURL::IsProtocolEqual(protocol, "mmsh") || CURL::IsProtocolEqual(protocol, "rtsp") || CURL::IsProtocolEqual(protocol, "rtmp") || CURL::IsProtocolEqual(protocol, "rtmpt") || CURL::IsProtocolEqual(protocol, "rtmpe") || CURL::IsProtocolEqual(protocol, "rtmpte") || CURL::IsProtocolEqual(protocol, "rtmps")) return true; return false; }
bool CPlaylistDirectory::GetDirectory(const CURL& url, CFileItemList &items) { int playlistTyp=PLAYLIST_NONE; if (url.IsProtocol("playlistmusic")) playlistTyp=PLAYLIST_MUSIC; else if (url.IsProtocol("playlistvideo")) playlistTyp=PLAYLIST_VIDEO; if (playlistTyp==PLAYLIST_NONE) return false; CPlayList& playlist = CServiceBroker::GetPlaylistPlayer().GetPlaylist(playlistTyp); items.Reserve(playlist.size()); for (int i = 0; i < playlist.size(); ++i) { CFileItemPtr item = playlist[i]; item->SetProperty("playlistposition", i); item->SetProperty("playlisttype", playlistTyp); //item->m_iprogramCount = i; // the programCount is set as items are added! items.Add(item); } return true; }
bool URIUtils::HasParentInHostname(const CURL& url) { return url.IsProtocol("zip") || url.IsProtocol("rar") || url.IsProtocol("apk") || url.IsProtocol("bluray") || url.IsProtocol("udf"); }
bool CPVRDirectory::Exists(const CURL& url) { if (!g_PVRManager.IsStarted()) return false; return (url.IsProtocol("pvr") && StringUtils::StartsWith(url.GetFileName(), "recordings")); }
bool CWin32File::SetHidden(const CURL& url, bool hidden) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.empty()) return false; const DWORD attrs = GetFileAttributesW(pathnameW.c_str()); if (attrs == INVALID_FILE_ATTRIBUTES || (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0) return false; // check whether attribute is already set/cleared if (((attrs & FILE_ATTRIBUTE_HIDDEN) != 0) == hidden) return true; bool result; if (hidden) result = (SetFileAttributesW(pathnameW.c_str(), attrs | FILE_ATTRIBUTE_HIDDEN) != 0); else result = SetFileAttributesW(pathnameW.c_str(), attrs & ~FILE_ATTRIBUTE_HIDDEN) != 0; if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state return result; }
CURL CBlurayDirectory::GetUnderlyingCURL(const CURL& url) { assert(url.IsProtocol("bluray")); std::string host = url.GetHostName(); std::string filename = url.GetFileName(); return CURL(host.append(filename)); }
std::string CXbtManager::NormalizePath(const CURL& path) { if (path.IsProtocol("xbt")) return path.GetHostName(); return path.Get(); }
bool CWin32File::Open(const CURL& url) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation if (m_hFile != INVALID_HANDLE_VALUE) { CLog::LogF(LOGERROR, "Attempt to open file without closing opened file object first"); return false; } std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" return false; // pathnameW is empty or points to device ("\\?\x:") assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); m_filepathnameW = pathnameW; m_hFile = CreateFileW(pathnameW.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state return m_hFile != INVALID_HANDLE_VALUE; }
StorageFolder CWinLibraryDirectory::GetRootFolder(const CURL& url) { if (!url.IsProtocol("win-lib")) return nullptr; std::string lib = url.GetHostName(); try { if (lib == "music") return KnownFolders::MusicLibrary(); if (lib == "video") return KnownFolders::VideosLibrary(); if (lib == "pictures") return KnownFolders::PicturesLibrary(); if (lib == "photos") return KnownFolders::CameraRoll(); if (lib == "documents") return KnownFolders::DocumentsLibrary(); if (lib == "removable") return KnownFolders::RemovableDevices(); } catch (const winrt::hresult_error& ex) { std::string strError = KODI::PLATFORM::WINDOWS::FromW(ex.message().c_str()); CLog::LogF(LOGERROR, "unexpected error occurs during WinRT API call: {}", strError); } return nullptr; }
bool CResourceFile::TranslatePath(const CURL &url, std::string &translatedPath) { translatedPath = url.Get(); // only handle resource:// paths if (!url.IsProtocol("resource")) return false; // the share name represents an identifier that can be mapped to an addon ID std::string addonId = url.GetShareName(); std::string filePath; if (url.GetFileName().length() > addonId.length()) filePath = url.GetFileName().substr(addonId.size() + 1); if (addonId.empty()) return false; AddonPtr addon; if (!CServiceBroker::GetAddonMgr().GetAddon(addonId, addon, ADDON_UNKNOWN, true) || addon == NULL) return false; std::shared_ptr<CResource> resource = std::dynamic_pointer_cast<ADDON::CResource>(addon); if (resource == NULL) return false; if (!resource->IsAllowed(filePath)) return false; translatedPath = CUtil::ValidatePath(resource->GetFullPath(filePath)); return true; }
std::string CDVDInputStreamFFmpeg::GetFileName() { CURL url = GetURL(); // rtmp options if (url.IsProtocol("rtmp") || url.IsProtocol("rtmpt") || url.IsProtocol("rtmpe") || url.IsProtocol("rtmpte") || url.IsProtocol("rtmps")) { std::vector<std::string> opts = StringUtils::Split(url.Get(), " "); if (opts.size() > 0) { return opts.front(); } return url.Get(); } return CDVDInputStream::GetFileName(); }
bool CFavouritesDirectory::Exists(const CURL& url) { if (url.IsProtocol("favourites")) { return XFILE::CFile::Exists("special://xbmc/system/favourites.xml") || XFILE::CFile::Exists(URIUtils::AddFileToFolder(CProfilesManager::GetInstance().GetProfileUserDataFolder(), "favourites.xml")); } return XFILE::CDirectory::Exists(url); //directly load the given file }
bool CFavouritesDirectory::GetDirectory(const CURL& url, CFileItemList &items) { items.Clear(); if (url.IsProtocol("favourites")) { return Load(items); //load the default favourite files } return LoadFavourites(url.Get(), items); //directly load the given file }
bool CWakeOnAccess::WakeUpHost(const CURL& url) { std::string hostName = url.GetHostName(); if (!hostName.empty()) return WakeUpHost(hostName, url.Get(), url.IsProtocol("upnp")); return true; }
std::string CBlurayFile::TranslatePath(const CURL& url) { assert(url.IsProtocol("bluray")); std::string host = url.GetHostName(); std::string filename = url.GetFileName(); if (host.empty() || filename.empty()) return ""; return host.append(filename); }
bool CWinLibraryDirectory::IsValid(const CURL& url) { if (!url.IsProtocol("win-lib")) return false; std::string lib = url.GetHostName(); if (lib == "music" || lib == "video" || lib == "pictures" || lib == "photos" || lib == "documents" || lib == "removable") return true; else return false; }
bool CWin32File::Rename(const CURL& urlCurrentName, const CURL& urlNewName) { assert((!m_smbFile && urlCurrentName.GetProtocol().empty()) || (m_smbFile && urlCurrentName.IsProtocol("smb"))); // function suitable only for local or SMB files assert((!m_smbFile && urlNewName.GetProtocol().empty()) || (m_smbFile && urlNewName.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation // TODO: check whether it's file or directory std::wstring curNameW(CWIN32Util::ConvertPathToWin32Form(urlCurrentName)); if (curNameW.empty()) return false; std::wstring newNameW(CWIN32Util::ConvertPathToWin32Form(urlNewName)); if (newNameW.empty()) return false; const bool result = (MoveFileExW(curNameW.c_str(), newNameW.c_str(), MOVEFILE_COPY_ALLOWED) != 0); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state return result; }
bool CFavouritesDirectory::Exists(const CURL& url) { if (url.IsProtocol("favourites")) { if (XFILE::CFile::Exists("special://xbmc/system/favourites.xml")) return true; const std::string favouritesXml = URIUtils::AddFileToFolder(m_profileManager->GetProfileUserDataFolder(), "favourites.xml"); return XFILE::CFile::Exists(favouritesXml); } return XFILE::CDirectory::Exists(url); }
std::string CMime::GetMimeType(const CURL &url, bool lookup) { std::string strMimeType; if( url.IsProtocol("shout") || url.IsProtocol("http") || url.IsProtocol("https")) { // If lookup is false, bail out early to leave mime type empty if (!lookup) return strMimeType; std::string strmime; XFILE::CCurlFile::GetMimeType(url, strmime); // try to get mime-type again but with an NSPlayer User-Agent // in order for server to provide correct mime-type. Allows us // to properly detect an MMS stream if (StringUtils::StartsWithNoCase(strmime, "video/x-ms-")) XFILE::CCurlFile::GetMimeType(url, strmime, "NSPlayer/11.00.6001.7000"); // make sure there are no options set in mime-type // mime-type can look like "video/x-ms-asf ; charset=utf8" size_t i = strmime.find(';'); if(i != std::string::npos) strmime.erase(i, strmime.length() - i); StringUtils::Trim(strmime); strMimeType = strmime; } else strMimeType = GetMimeType(url.GetFileType()); // if it's still empty set to an unknown type if (strMimeType.empty()) strMimeType = "application/octet-stream"; return strMimeType; }
bool CWin32File::Exists(const CURL& url) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.empty()) return false; const DWORD attrs = GetFileAttributesW(pathnameW.c_str()); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0; }
bool CWin32File::Delete(const CURL& url) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.empty()) return false; const bool result = (DeleteFileW(pathnameW.c_str()) != 0); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state return result; }
StorageFolder^ CWinLibraryDirectory::GetRootFolder(const CURL& url) { if (!url.IsProtocol("win-lib")) return nullptr; std::string lib = url.GetHostName(); if (lib == "music") return KnownFolders::MusicLibrary; if (lib == "video") return KnownFolders::VideosLibrary; if (lib == "pictures") return KnownFolders::PicturesLibrary; if (lib == "photos") return KnownFolders::CameraRoll; if (lib == "documents") return KnownFolders::DocumentsLibrary; if (lib == "removable") return KnownFolders::RemovableDevices; return nullptr; }
bool CZipDirectory::GetDirectory(const CURL& urlOrig, CFileItemList& items) { CURL urlZip(urlOrig); /* if this isn't a proper archive path, assume it's the path to a archive file */ if (!urlOrig.IsProtocol("zip")) urlZip = URIUtils::CreateArchivePath("zip", urlOrig); std::vector<SZipEntry> zipEntries; if (!g_ZipManager.GetZipList(urlZip, zipEntries)) return false; // prepare the ZIP entries for directorization DirectorizeEntries<SZipEntry> entries; entries.reserve(zipEntries.size()); for (const auto& zipEntry : zipEntries) entries.push_back(DirectorizeEntry<SZipEntry>(zipEntry.name, zipEntry)); // directorize the ZIP entries into files and directories Directorize(urlZip, entries, ZipEntryToFileItem, items); return true; }
bool CWin32File::OpenForWrite(const CURL& url, bool bOverWrite /*= false*/) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation if (m_hFile != INVALID_HANDLE_VALUE) return false; std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" return false; // pathnameW is empty or points to device ("\\?\x:") assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); m_hFile = CreateFileW(pathnameW.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverWrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state if (m_hFile == INVALID_HANDLE_VALUE) return false; const bool newlyCreated = (GetLastError() != ERROR_ALREADY_EXISTS); m_filepathnameW = pathnameW; if (!newlyCreated) { if (Seek(0, SEEK_SET) != 0) { CLog::LogF(LOGERROR, "Can't move i/o pointer"); Close(); if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // indicate internal errors return false; } } else { // newly created file /* set "hidden" attribute if filename starts with a period */ size_t lastSlash = pathnameW.rfind(L'\\'); if (lastSlash < pathnameW.length() - 1 // is two checks in one: lastSlash != std::string::npos && lastSlash + 1 < pathnameW.length() && pathnameW[lastSlash + 1] == L'.') { FILE_BASIC_INFO basicInfo; bool hiddenSet = false; if (GetFileInformationByHandleEx(m_hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)) != 0) { if ((basicInfo.FileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) hiddenSet = true; else { basicInfo.FileAttributes |= FILE_ATTRIBUTE_HIDDEN; hiddenSet = SetFileInformationByHandle(m_hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)) != 0; } } if (!hiddenSet) CLog::LogFW(LOGWARNING, L"Can't set hidden attribute for file \"%ls\"", pathnameW.c_str()); } } m_allowWrite = true; return true; }
bool URIUtils::HasEncodedHostname(const CURL& url) { return HasParentInHostname(url) || url.IsProtocol("musicsearch") || url.IsProtocol( "image"); }
bool CZeroconfDirectory::GetDirectory(const CURL& url, CFileItemList &items) { assert(url.IsProtocol("zeroconf")); std::string strPath = url.Get(); std::string path = strPath.substr(11, strPath.length()); URIUtils::RemoveSlashAtEnd(path); if(path.empty()) { std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices(); for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it) { //only use discovered services we can connect to through directory std::string tmp; if(GetXBMCProtocol(it->GetType(), tmp)) { CFileItemPtr item(new CFileItem("", true)); CURL url; url.SetProtocol("zeroconf"); std::string service_path(CURL::Encode(CZeroconfBrowser::ZeroconfService::toPath(*it))); url.SetFileName(service_path); item->SetPath(url.Get()); //now do the formatting std::string protocol = GetHumanReadableProtocol(it->GetType()); item->SetLabel(it->GetName() + " (" + protocol + ")"); item->SetLabelPreformated(true); //just set the default folder icon item->FillInDefaultIcon(); items.Add(item); } } return true; } else { //decode the path first std::string decoded(CURL::Decode(path)); try { CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded); if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service)) { CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str()); return false; } else { assert(!zeroconf_service.GetIP().empty()); CURL service; service.SetPort(zeroconf_service.GetPort()); service.SetHostName(zeroconf_service.GetIP()); //do protocol conversion (_smb._tcp -> smb) //! @todo try automatic conversion -> remove leading '_' and '._tcp'? std::string protocol; if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol)) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str()); return false; } service.SetProtocol(protocol); //first try to show the txt-record defined path if any if(GetDirectoryFromTxtRecords(zeroconf_service, service, items)) { return true; } else//no txt record path - so let the CDirectory handler show the folders { return CDirectory::GetDirectory(service.Get(), items, "", DIR_FLAG_ALLOW_PROMPT); } } } catch (std::runtime_error& e) { CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what()); return false; } } }
int CWin32File::Stat(const CURL& url, struct __stat64* statData) { assert((!m_smbFile && url.GetProtocol().empty()) || (m_smbFile && url.IsProtocol("smb"))); // function suitable only for local or SMB files if (m_smbFile) m_lastSMBFileErr = ERROR_INVALID_DATA; // used to indicate internal errors, cleared by successful file operation if (!statData) return -1; std::wstring pathnameW(CWIN32Util::ConvertPathToWin32Form(url)); if (pathnameW.empty()) { errno = ENOENT; return -1; } if (pathnameW.length() <= 6) // 6 is length of "\\?\x:" return -1; // pathnameW is empty or points to device ("\\?\x:"), on win32 stat() for devices is not supported assert((pathnameW.compare(4, 4, L"UNC\\", 4) == 0 && m_smbFile) || !m_smbFile); // get maximum information about file from search function HANDLE hSearch; WIN32_FIND_DATAW findData; if (CSysInfo::IsWindowsVersionAtLeast(CSysInfo::WindowsVersionWin7)) hSearch = FindFirstFileExW(pathnameW.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, NULL, 0); else hSearch = FindFirstFileExW(pathnameW.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); if (m_smbFile) m_lastSMBFileErr = GetLastError(); // set real error state if (hSearch == INVALID_HANDLE_VALUE) return -1; FindClose(hSearch); /* set st_gid */ statData->st_gid = 0; // UNIX group ID is always zero on Win32 /* set st_uid */ statData->st_uid = 0; // UNIX user ID is always zero on Win32 /* set st_ino */ statData->st_ino = 0; // inode number is not implemented on Win32 /* set st_size */ statData->st_size = (__int64(findData.nFileSizeHigh) << 32) + __int64(findData.nFileSizeLow); /* set st_dev and st_rdev */ if (!m_smbFile) { assert(pathnameW.compare(0, 4, L"\\\\?\\", 4) == 0); assert(pathnameW.length() >= 7); // '7' is the minimal length of "\\?\x:\" assert(pathnameW[5] == L':'); const wchar_t driveLetter = pathnameW[4]; assert((driveLetter >= L'A' && driveLetter <= L'Z') || (driveLetter >= L'a' && driveLetter <= L'z')); statData->st_dev = (driveLetter >= L'a') ? driveLetter - L'a' : driveLetter - L'A'; } else statData->st_dev = 0; statData->st_rdev = statData->st_dev; const HANDLE hFile = CreateFileW(pathnameW.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* set st_nlink */ statData->st_nlink = 1; // fallback value if (hFile != INVALID_HANDLE_VALUE) { _FILE_STANDARD_INFO stdInfo; if (GetFileInformationByHandleEx(hFile, FileStandardInfo, &stdInfo, sizeof(stdInfo)) != 0) statData->st_nlink = (stdInfo.NumberOfLinks > SHORT_MAX) ? SHORT_MAX : short(stdInfo.NumberOfLinks); } /* set st_mtime, st_atime, st_ctime */ statData->st_mtime = 0; statData->st_atime = 0; statData->st_ctime = 0; if (hFile != INVALID_HANDLE_VALUE) { FILE_BASIC_INFO basicInfo; if (GetFileInformationByHandleEx(hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)) != 0) { statData->st_mtime = CWIN32Util::fileTimeToTimeT(basicInfo.LastWriteTime); statData->st_atime = CWIN32Util::fileTimeToTimeT(basicInfo.LastAccessTime); statData->st_ctime = CWIN32Util::fileTimeToTimeT(basicInfo.CreationTime); } CloseHandle(hFile); } if (statData->st_mtime == 0) statData->st_mtime = CWIN32Util::fileTimeToTimeT(findData.ftLastWriteTime); if (statData->st_atime == 0) statData->st_atime = CWIN32Util::fileTimeToTimeT(findData.ftLastAccessTime); if (statData->st_atime == 0) statData->st_atime = statData->st_mtime; if (statData->st_ctime == 0) statData->st_ctime = CWIN32Util::fileTimeToTimeT(findData.ftCreationTime); if (statData->st_ctime == 0) statData->st_ctime = statData->st_mtime; /* set st_mode */ statData->st_mode = _S_IREAD; // Always assume Read permission for file owner if ((findData.dwFileAttributes & FILE_READ_ONLY) == 0) statData->st_mode |= _S_IWRITE; // Write possible if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) statData->st_mode |= _S_IFDIR | _S_IEXEC; // directory else { statData->st_mode |= _S_IFREG; // file // following large piece of code is disabled // as it intended only to set _S_IEXEC flag // which is not used by callers #ifdef WIN32_USE_FILE_STAT_MAX_INFO // set _S_IEXEC if file has executable extension const size_t lastDot = pathnameW.rfind(L'.'); if (lastDot != std::wstring::npos && pathnameW.rfind(L'\\') < lastDot) { // file has some extension const std::wstring fileExt(pathnameW, lastDot); XUTILS::auto_buffer buf(32767 * sizeof(wchar_t)); // maximum possible size const DWORD envRes = GetEnvironmentVariableW(L"PATHEXT", (wchar_t*)buf.get(), buf.size() / sizeof(wchar_t)); std::vector<std::wstring> listExts; if (envRes == 0 || envRes > (buf.size() / sizeof(wchar_t))) { buf.clear(); static const wchar_t* extArr[] = { L".exe", L".bat", L".cmd", L".com" }; listExts.assign(extArr, extArr + (sizeof(extArr) / sizeof(extArr[0]))); } else { std::wstring envPathextW((wchar_t*)buf.get(), envRes); buf.clear(); size_t posExt = envPathextW.find_first_not_of(L';'); // skip ';' at the start while (posExt != std::wstring::npos) { const size_t posSemicol = envPathextW.find(L';', posExt); listExts.push_back(envPathextW.substr(posExt, posSemicol - posExt)); posExt = envPathextW.find_first_not_of(L";", posSemicol); } } const wchar_t* const fileExtC = fileExt.c_str(); for (std::vector<std::wstring>::const_iterator it = listExts.cbegin(); it != listExts.cend(); ++it) { if (_wcsicmp(fileExtC, it->c_str()) == 0) { statData->st_mode |= _S_IEXEC; // file can be executed break; } } } #endif // WIN32_USE_FILE_STAT_MAX_INFO } // copy user RWX rights to group rights statData->st_mode |= (statData->st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC)) >> 3; // copy user RWX rights to other rights statData->st_mode |= (statData->st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC)) >> 6; return 0; }
CGUIViewState* CGUIViewState::GetViewState(int windowId, const CFileItemList& items) { // don't expect derived classes to clear the sources m_sources.clear(); if (windowId == 0) return GetViewState(g_windowManager.GetActiveWindow(),items); const CURL url=items.GetURL(); if (items.IsAddonsPath()) return new CGUIViewStateAddonBrowser(items); if (items.HasSortDetails()) return new CGUIViewStateFromItems(items); if (url.IsProtocol("musicdb")) return new CGUIViewStateMusicDatabase(items); if (url.IsProtocol("musicsearch")) return new CGUIViewStateMusicSearch(items); if (items.IsSmartPlayList() || url.IsProtocol("upnp") || items.IsLibraryFolder()) { if (items.GetContent() == "songs" || items.GetContent() == "albums" || items.GetContent() == "mixed") return new CGUIViewStateMusicSmartPlaylist(items); else if (items.GetContent() == "musicvideos") return new CGUIViewStateVideoMusicVideos(items); else if (items.GetContent() == "tvshows") return new CGUIViewStateVideoTVShows(items); else if (items.GetContent() == "episodes") return new CGUIViewStateVideoEpisodes(items); else if (items.GetContent() == "movies") return new CGUIViewStateVideoMovies(items); } if (url.IsProtocol("library")) return new CGUIViewStateLibrary(items); if (items.IsPlayList()) return new CGUIViewStateMusicPlaylist(items); if (items.GetPath() == "special://musicplaylists/") return new CGUIViewStateWindowMusicNav(items); if (url.IsProtocol("androidapp")) return new CGUIViewStateWindowPrograms(items); if (url.IsProtocol("activities")) return new CGUIViewStateEventLog(items); if (windowId == WINDOW_MUSIC_NAV) return new CGUIViewStateWindowMusicNav(items); if (windowId == WINDOW_MUSIC_PLAYLIST) return new CGUIViewStateWindowMusicPlaylist(items); if (windowId == WINDOW_MUSIC_PLAYLIST_EDITOR) return new CGUIViewStateWindowMusicNav(items); if (windowId == WINDOW_VIDEO_NAV) return new CGUIViewStateWindowVideoNav(items); if (windowId == WINDOW_VIDEO_PLAYLIST) return new CGUIViewStateWindowVideoPlaylist(items); if (windowId == WINDOW_TV_CHANNELS) return new CGUIViewStateWindowPVRChannels(windowId, items); if (windowId == WINDOW_TV_RECORDINGS) return new CGUIViewStateWindowPVRRecordings(windowId, items); if (windowId == WINDOW_TV_GUIDE) return new CGUIViewStateWindowPVRGuide(windowId, items); if (windowId == WINDOW_TV_TIMERS) return new CGUIViewStateWindowPVRTimers(windowId, items); if (windowId == WINDOW_TV_TIMER_RULES) return new CGUIViewStateWindowPVRTimers(windowId, items); if (windowId == WINDOW_TV_SEARCH) return new CGUIViewStateWindowPVRSearch(windowId, items); if (windowId == WINDOW_RADIO_CHANNELS) return new CGUIViewStateWindowPVRChannels(windowId, items); if (windowId == WINDOW_RADIO_RECORDINGS) return new CGUIViewStateWindowPVRRecordings(windowId, items); if (windowId == WINDOW_RADIO_GUIDE) return new CGUIViewStateWindowPVRGuide(windowId, items); if (windowId == WINDOW_RADIO_TIMERS) return new CGUIViewStateWindowPVRTimers(windowId, items); if (windowId == WINDOW_RADIO_TIMER_RULES) return new CGUIViewStateWindowPVRTimers(windowId, items); if (windowId == WINDOW_RADIO_SEARCH) return new CGUIViewStateWindowPVRSearch(windowId, items); if (windowId == WINDOW_PICTURES) return new CGUIViewStateWindowPictures(items); if (windowId == WINDOW_PROGRAMS) return new CGUIViewStateWindowPrograms(items); if (windowId == WINDOW_GAMES) return new GAME::CGUIViewStateWindowGames(items); if (windowId == WINDOW_ADDON_BROWSER) return new CGUIViewStateAddonBrowser(items); if (windowId == WINDOW_EVENT_LOG) return new CGUIViewStateEventLog(items); // Use as fallback/default return new CGUIViewStateGeneral(items); }
std::string CSpecialProtocol::TranslatePath(const CURL &url) { // check for special-protocol, if not, return if (!url.IsProtocol("special")) { #if defined(TARGET_POSIX) && defined(_DEBUG) std::string path(url.Get()); if (path.length() >= 2 && path[1] == ':') { CLog::Log(LOGWARNING, "Trying to access old style dir: %s\n", path.c_str()); // printf("Trying to access old style dir: %s\n", path.c_str()); } #endif return url.Get(); } std::string FullFileName = url.GetFileName(); std::string translatedPath; std::string FileName; std::string RootDir; // Split up into the special://root and the rest of the filename size_t pos = FullFileName.find('/'); if (pos != std::string::npos && pos > 1) { RootDir = FullFileName.substr(0, pos); if (pos < FullFileName.size()) FileName = FullFileName.substr(pos + 1); } else RootDir = FullFileName; if (RootDir == "subtitles") translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("subtitles.custompath"), FileName); else if (RootDir == "userdata") translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetUserDataFolder(), FileName); else if (RootDir == "database") translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetDatabaseFolder(), FileName); else if (RootDir == "thumbnails") translatedPath = URIUtils::AddFileToFolder(CProfilesManager::Get().GetThumbnailsFolder(), FileName); else if (RootDir == "recordings" || RootDir == "cdrips") translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("audiocds.recordingpath"), FileName); else if (RootDir == "screenshots") translatedPath = URIUtils::AddFileToFolder(CSettings::Get().GetString("debug.screenshotpath"), FileName); else if (RootDir == "musicplaylists") translatedPath = URIUtils::AddFileToFolder(CUtil::MusicPlaylistsLocation(), FileName); else if (RootDir == "videoplaylists") translatedPath = URIUtils::AddFileToFolder(CUtil::VideoPlaylistsLocation(), FileName); else if (RootDir == "skin") translatedPath = URIUtils::AddFileToFolder(g_graphicsContext.GetMediaDir(), FileName); else if (RootDir == "logpath") translatedPath = URIUtils::AddFileToFolder(g_advancedSettings.m_logFolder, FileName); // from here on, we have our "real" special paths else if (RootDir == "xbmc" || RootDir == "xbmcbin" || RootDir == "home" || RootDir == "userhome" || RootDir == "temp" || RootDir == "profile" || RootDir == "masterprofile" || RootDir == "frameworks") { std::string basePath = GetPath(RootDir); if (!basePath.empty()) translatedPath = URIUtils::AddFileToFolder(basePath, FileName); else translatedPath.clear(); } // check if we need to recurse in if (URIUtils::IsSpecial(translatedPath)) { // we need to recurse in, as there may be multiple translations required return TranslatePath(translatedPath); } // Validate the final path, just in case return CUtil::ValidatePath(translatedPath); }