diff --git a/include/file_entry.h b/include/file_entry.h index 584993d..daac485 100644 --- a/include/file_entry.h +++ b/include/file_entry.h @@ -62,6 +62,7 @@ private: bool IsIgnore(const std::string &filename) const; static bool RemoveAllDirInner(const FileEntry &entry); static bool CreateDirsInner(const std::string &path, std::string::size_type offset); + static std::string AdapateLongPath(const std::string &path); FilePath filePath_; bool isFile_; static const std::string SEPARATE; diff --git a/include/resource_data.h b/include/resource_data.h index 85a7d95..94b007b 100644 --- a/include/resource_data.h +++ b/include/resource_data.h @@ -33,6 +33,7 @@ const static std::string RESOURCE_INDEX_FILE = "resources.index"; const static std::string SEPARATOR = "/"; const static std::string WIN_SEPARATOR = "\\"; const static std::string NEW_LINE_PATH = "\r\nat "; +const static std::string LONG_PATH_HEAD = "\\\\?\\"; const static std::string ID_DEFINED_INDENTATION = " "; const static int32_t VERSION_MAX_LEN = 128; const static int32_t INT_TO_BYTES = sizeof(uint32_t); diff --git a/src/file_entry.cpp b/src/file_entry.cpp index c335b1b..e0d1cfb 100644 --- a/src/file_entry.cpp +++ b/src/file_entry.cpp @@ -14,16 +14,17 @@ */ #include "file_entry.h" +#include #include #include #include "dirent.h" #include "sys/stat.h" #include "unistd.h" -#include #ifdef _WIN32 -#include "windows.h" #include "shlwapi.h" +#include "windows.h" #endif +#include "resource_data.h" namespace OHOS { namespace Global { @@ -63,7 +64,7 @@ const vector> FileEntry::GetChilds() const #ifdef _WIN32 WIN32_FIND_DATA findData; string temp(filePath + "\\*.*"); - HANDLE handle = FindFirstFile(temp.c_str(), &findData); + HANDLE handle = FindFirstFile(AdapateLongPath(temp).c_str(), &findData); if (handle == INVALID_HANDLE_VALUE) { return children; } @@ -112,9 +113,7 @@ const FileEntry::FilePath &FileEntry::GetFilePath() const bool FileEntry::Exist(const string &path) { #ifdef _WIN32 - if (!PathFileExists(path.c_str())) { - return false; - } + return PathFileExists(AdapateLongPath(path).c_str()); #else struct stat s; if (stat(path.c_str(), &s) != 0) { @@ -146,15 +145,15 @@ bool FileEntry::CreateDirs(const string &path) bool FileEntry::CopyFileInner(const string &src, const string &dst) { #ifdef _WIN32 - if (!CopyFile(src.c_str(), dst.c_str(), false)) { - cerr << "Error: CopyFile '" << src << "' to '" << dst << "' failed." << endl; + if (!CopyFile(AdapateLongPath(src).c_str(), AdapateLongPath(dst).c_str(), false)) { + cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'. reason:" << strerror(errno) << endl; return false; } #else ifstream in(src, ios::binary); ofstream out(dst, ios::binary); if (!in || !out) { - cerr << "Error: open failed '" << src << "' or '" << dst << "'." << endl; + cerr << "Error: open failed '" << src << "' or '" << dst << "'. reason:" << strerror(errno) << endl; return false; } out << in.rdbuf(); @@ -165,7 +164,7 @@ bool FileEntry::CopyFileInner(const string &src, const string &dst) bool FileEntry::IsDirectory(const string &path) { #ifdef _WIN32 - if (!PathIsDirectory(path.c_str())) { + if (!PathIsDirectory(AdapateLongPath(path).c_str())) { return false; } return true; @@ -180,7 +179,7 @@ string FileEntry::RealPath(const string &path) { #ifdef _WIN32 char buffer[MAX_PATH]; - if (!PathCanonicalize(buffer, path.c_str())) { + if (!PathCanonicalize(buffer, AdapateLongPath(path).c_str())) { return ""; } @@ -281,11 +280,15 @@ bool FileEntry::IsIgnore(const string &filename) const bool FileEntry::RemoveAllDirInner(const FileEntry &entry) { + string path = entry.GetFilePath().GetPath(); if (entry.IsFile()) { - bool result = remove(entry.GetFilePath().GetPath().c_str()) == 0; +#if _WIN32 + bool result = remove(AdapateLongPath(path).c_str()) == 0; +#else + bool result = remove(path.c_str()) == 0; +#endif if (!result) { - cerr << "Error: remove failed '" << entry.GetFilePath().GetPath(); - cerr << "', reason: " << strerror(errno) << endl; + cerr << "Error: remove file '" << path << "' failed, reason: " << strerror(errno) << endl; return false; } return true; @@ -296,7 +299,16 @@ bool FileEntry::RemoveAllDirInner(const FileEntry &entry) return false; } } - return rmdir(entry.GetFilePath().GetPath().c_str()) == 0; +#if _WIN32 + bool result = rmdir(AdapateLongPath(path).c_str()) == 0; +#else + bool result = rmdir(path.c_str()) == 0; +#endif + if (!result) { + cerr << "Error: remove directory '" << path << "' failed, reason: " << strerror(errno) << endl; + return false; + } + return true; } bool FileEntry::CreateDirsInner(const string &path, string::size_type offset) @@ -304,7 +316,7 @@ bool FileEntry::CreateDirsInner(const string &path, string::size_type offset) string::size_type pos = path.find_first_of(SEPARATE.front(), offset); if (pos == string::npos) { #if _WIN32 - return CreateDirectory(path.c_str(), nullptr) != 0; + return CreateDirectory(AdapateLongPath(path).c_str(), nullptr) != 0; #else return mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0; #endif @@ -313,7 +325,7 @@ bool FileEntry::CreateDirsInner(const string &path, string::size_type offset) string subPath = path.substr(0, pos + 1); if (!Exist(subPath)) { #if _WIN32 - if (!CreateDirectory(subPath.c_str(), nullptr)) { + if (!CreateDirectory(AdapateLongPath(subPath).c_str(), nullptr)) { #else if (mkdir(subPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { #endif @@ -347,6 +359,16 @@ void FileEntry::FilePath::Init() extension_ = filename_.substr(pos); } } + +#if _WIN32 +string FileEntry::AdapateLongPath(const string &path) +{ + if (path.size() >= MAX_PATH -12) { //the max file path can not exceed 260 - 12 + return LONG_PATH_HEAD + path; + } + return path; +} +#endif } } } diff --git a/src/resource_util.cpp b/src/resource_util.cpp index 5ac0280..5cd8976 100644 --- a/src/resource_util.cpp +++ b/src/resource_util.cpp @@ -213,11 +213,7 @@ ResType ResourceUtil::GetResTypeFromString(const string &type) bool ResourceUtil::CopyFleInner(const string &src, const string &dst) { - if (!FileEntry::CopyFileInner(src, dst)) { - cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'." << endl; - return false; - } - return true; + return FileEntry::CopyFileInner(src, dst); } bool ResourceUtil::CreateDirs(const string &filePath) @@ -227,7 +223,7 @@ bool ResourceUtil::CreateDirs(const string &filePath) } if (!FileEntry::CreateDirs(filePath)) { - cerr << "Error: create dir fail '" << filePath << "'." << endl; + cerr << "Error: create dir '" << filePath << "' failed, reason:" << strerror(errno) << endl; return false; } return true;