1370b324cSopenharmony_ci// ExtractingFilePath.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "../../../Common/Wildcard.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "../../../Windows/FileName.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#include "ExtractingFilePath.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ciextern 12370b324cSopenharmony_cibool g_PathTrailReplaceMode; 13370b324cSopenharmony_cibool g_PathTrailReplaceMode = 14370b324cSopenharmony_ci #ifdef _WIN32 15370b324cSopenharmony_ci true 16370b324cSopenharmony_ci #else 17370b324cSopenharmony_ci false 18370b324cSopenharmony_ci #endif 19370b324cSopenharmony_ci ; 20370b324cSopenharmony_ci 21370b324cSopenharmony_ci 22370b324cSopenharmony_ci#ifdef _WIN32 23370b324cSopenharmony_cistatic void ReplaceIncorrectChars(UString &s) 24370b324cSopenharmony_ci{ 25370b324cSopenharmony_ci { 26370b324cSopenharmony_ci for (unsigned i = 0; i < s.Len(); i++) 27370b324cSopenharmony_ci { 28370b324cSopenharmony_ci wchar_t c = s[i]; 29370b324cSopenharmony_ci if ( 30370b324cSopenharmony_ci #ifdef _WIN32 31370b324cSopenharmony_ci c == ':' || c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"' 32370b324cSopenharmony_ci || c == '/' 33370b324cSopenharmony_ci // || c == 0x202E // RLO 34370b324cSopenharmony_ci || 35370b324cSopenharmony_ci #endif 36370b324cSopenharmony_ci c == WCHAR_PATH_SEPARATOR) 37370b324cSopenharmony_ci { 38370b324cSopenharmony_ci #if WCHAR_PATH_SEPARATOR != L'/' 39370b324cSopenharmony_ci // 22.00 : WSL replacement for backslash 40370b324cSopenharmony_ci if (c == WCHAR_PATH_SEPARATOR) 41370b324cSopenharmony_ci c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; 42370b324cSopenharmony_ci else 43370b324cSopenharmony_ci #endif 44370b324cSopenharmony_ci c = '_'; 45370b324cSopenharmony_ci s.ReplaceOneCharAtPos(i, 46370b324cSopenharmony_ci c 47370b324cSopenharmony_ci // (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters 48370b324cSopenharmony_ci ); 49370b324cSopenharmony_ci } 50370b324cSopenharmony_ci } 51370b324cSopenharmony_ci } 52370b324cSopenharmony_ci 53370b324cSopenharmony_ci if (g_PathTrailReplaceMode) 54370b324cSopenharmony_ci { 55370b324cSopenharmony_ci /* 56370b324cSopenharmony_ci // if (g_PathTrailReplaceMode == 1) 57370b324cSopenharmony_ci { 58370b324cSopenharmony_ci if (!s.IsEmpty()) 59370b324cSopenharmony_ci { 60370b324cSopenharmony_ci wchar_t c = s.Back(); 61370b324cSopenharmony_ci if (c == '.' || c == ' ') 62370b324cSopenharmony_ci { 63370b324cSopenharmony_ci // s += (wchar_t)(0x9c); // STRING TERMINATOR 64370b324cSopenharmony_ci s += (wchar_t)'_'; 65370b324cSopenharmony_ci } 66370b324cSopenharmony_ci } 67370b324cSopenharmony_ci } 68370b324cSopenharmony_ci else 69370b324cSopenharmony_ci */ 70370b324cSopenharmony_ci { 71370b324cSopenharmony_ci unsigned i; 72370b324cSopenharmony_ci for (i = s.Len(); i != 0;) 73370b324cSopenharmony_ci { 74370b324cSopenharmony_ci wchar_t c = s[i - 1]; 75370b324cSopenharmony_ci if (c != '.' && c != ' ') 76370b324cSopenharmony_ci break; 77370b324cSopenharmony_ci i--; 78370b324cSopenharmony_ci s.ReplaceOneCharAtPos(i, '_'); 79370b324cSopenharmony_ci // s.ReplaceOneCharAtPos(i, (c == ' ' ? (wchar_t)(0x2423) : (wchar_t)0x00B7)); 80370b324cSopenharmony_ci } 81370b324cSopenharmony_ci /* 82370b324cSopenharmony_ci if (g_PathTrailReplaceMode > 1 && i != s.Len()) 83370b324cSopenharmony_ci { 84370b324cSopenharmony_ci s.DeleteFrom(i); 85370b324cSopenharmony_ci } 86370b324cSopenharmony_ci */ 87370b324cSopenharmony_ci } 88370b324cSopenharmony_ci } 89370b324cSopenharmony_ci} 90370b324cSopenharmony_ci#endif 91370b324cSopenharmony_ci 92370b324cSopenharmony_ci/* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream. 93370b324cSopenharmony_ci But colon in postfix ":$DATA" is allowed. 94370b324cSopenharmony_ci WIN32 functions don't allow empty alt stream name "name:" */ 95370b324cSopenharmony_ci 96370b324cSopenharmony_civoid Correct_AltStream_Name(UString &s) 97370b324cSopenharmony_ci{ 98370b324cSopenharmony_ci unsigned len = s.Len(); 99370b324cSopenharmony_ci const unsigned kPostfixSize = 6; 100370b324cSopenharmony_ci if (s.Len() >= kPostfixSize 101370b324cSopenharmony_ci && StringsAreEqualNoCase_Ascii(s.RightPtr(kPostfixSize), ":$DATA")) 102370b324cSopenharmony_ci len -= kPostfixSize; 103370b324cSopenharmony_ci for (unsigned i = 0; i < len; i++) 104370b324cSopenharmony_ci { 105370b324cSopenharmony_ci wchar_t c = s[i]; 106370b324cSopenharmony_ci if (c == ':' || c == '\\' || c == '/' 107370b324cSopenharmony_ci || c == 0x202E // RLO 108370b324cSopenharmony_ci ) 109370b324cSopenharmony_ci s.ReplaceOneCharAtPos(i, '_'); 110370b324cSopenharmony_ci } 111370b324cSopenharmony_ci if (s.IsEmpty()) 112370b324cSopenharmony_ci s = '_'; 113370b324cSopenharmony_ci} 114370b324cSopenharmony_ci 115370b324cSopenharmony_ci#ifdef _WIN32 116370b324cSopenharmony_ci 117370b324cSopenharmony_cistatic const unsigned g_ReservedWithNum_Index = 4; 118370b324cSopenharmony_ci 119370b324cSopenharmony_cistatic const char * const g_ReservedNames[] = 120370b324cSopenharmony_ci{ 121370b324cSopenharmony_ci "CON", "PRN", "AUX", "NUL", 122370b324cSopenharmony_ci "COM", "LPT" 123370b324cSopenharmony_ci}; 124370b324cSopenharmony_ci 125370b324cSopenharmony_cistatic bool IsSupportedName(const UString &name) 126370b324cSopenharmony_ci{ 127370b324cSopenharmony_ci for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ReservedNames); i++) 128370b324cSopenharmony_ci { 129370b324cSopenharmony_ci const char *reservedName = g_ReservedNames[i]; 130370b324cSopenharmony_ci unsigned len = MyStringLen(reservedName); 131370b324cSopenharmony_ci if (name.Len() < len) 132370b324cSopenharmony_ci continue; 133370b324cSopenharmony_ci if (!name.IsPrefixedBy_Ascii_NoCase(reservedName)) 134370b324cSopenharmony_ci continue; 135370b324cSopenharmony_ci if (i >= g_ReservedWithNum_Index) 136370b324cSopenharmony_ci { 137370b324cSopenharmony_ci wchar_t c = name[len]; 138370b324cSopenharmony_ci if (c < L'0' || c > L'9') 139370b324cSopenharmony_ci continue; 140370b324cSopenharmony_ci len++; 141370b324cSopenharmony_ci } 142370b324cSopenharmony_ci for (;;) 143370b324cSopenharmony_ci { 144370b324cSopenharmony_ci wchar_t c = name[len++]; 145370b324cSopenharmony_ci if (c == 0 || c == '.') 146370b324cSopenharmony_ci return false; 147370b324cSopenharmony_ci if (c != ' ') 148370b324cSopenharmony_ci break; 149370b324cSopenharmony_ci } 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci return true; 152370b324cSopenharmony_ci} 153370b324cSopenharmony_ci 154370b324cSopenharmony_cistatic void CorrectUnsupportedName(UString &name) 155370b324cSopenharmony_ci{ 156370b324cSopenharmony_ci if (!IsSupportedName(name)) 157370b324cSopenharmony_ci name.InsertAtFront(L'_'); 158370b324cSopenharmony_ci} 159370b324cSopenharmony_ci 160370b324cSopenharmony_ci#endif 161370b324cSopenharmony_ci 162370b324cSopenharmony_cistatic void Correct_PathPart(UString &s) 163370b324cSopenharmony_ci{ 164370b324cSopenharmony_ci // "." and ".." 165370b324cSopenharmony_ci if (s.IsEmpty()) 166370b324cSopenharmony_ci return; 167370b324cSopenharmony_ci 168370b324cSopenharmony_ci if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) 169370b324cSopenharmony_ci s.Empty(); 170370b324cSopenharmony_ci #ifdef _WIN32 171370b324cSopenharmony_ci else 172370b324cSopenharmony_ci ReplaceIncorrectChars(s); 173370b324cSopenharmony_ci #endif 174370b324cSopenharmony_ci} 175370b324cSopenharmony_ci 176370b324cSopenharmony_ci// static const char * const k_EmptyReplaceName = "[]"; 177370b324cSopenharmony_cistatic const char k_EmptyReplaceName = '_'; 178370b324cSopenharmony_ci 179370b324cSopenharmony_ciUString Get_Correct_FsFile_Name(const UString &name) 180370b324cSopenharmony_ci{ 181370b324cSopenharmony_ci UString res = name; 182370b324cSopenharmony_ci Correct_PathPart(res); 183370b324cSopenharmony_ci 184370b324cSopenharmony_ci #ifdef _WIN32 185370b324cSopenharmony_ci CorrectUnsupportedName(res); 186370b324cSopenharmony_ci #endif 187370b324cSopenharmony_ci 188370b324cSopenharmony_ci if (res.IsEmpty()) 189370b324cSopenharmony_ci res = k_EmptyReplaceName; 190370b324cSopenharmony_ci return res; 191370b324cSopenharmony_ci} 192370b324cSopenharmony_ci 193370b324cSopenharmony_ci 194370b324cSopenharmony_civoid Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir) 195370b324cSopenharmony_ci{ 196370b324cSopenharmony_ci unsigned i = 0; 197370b324cSopenharmony_ci 198370b324cSopenharmony_ci if (absIsAllowed) 199370b324cSopenharmony_ci { 200370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 201370b324cSopenharmony_ci bool isDrive = false; 202370b324cSopenharmony_ci #endif 203370b324cSopenharmony_ci 204370b324cSopenharmony_ci if (parts[0].IsEmpty()) 205370b324cSopenharmony_ci { 206370b324cSopenharmony_ci i = 1; 207370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 208370b324cSopenharmony_ci if (parts.Size() > 1 && parts[1].IsEmpty()) 209370b324cSopenharmony_ci { 210370b324cSopenharmony_ci i = 2; 211370b324cSopenharmony_ci if (parts.Size() > 2 && parts[2] == L"?") 212370b324cSopenharmony_ci { 213370b324cSopenharmony_ci i = 3; 214370b324cSopenharmony_ci if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) 215370b324cSopenharmony_ci { 216370b324cSopenharmony_ci isDrive = true; 217370b324cSopenharmony_ci i = 4; 218370b324cSopenharmony_ci } 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci } 221370b324cSopenharmony_ci #endif 222370b324cSopenharmony_ci } 223370b324cSopenharmony_ci #if defined(_WIN32) && !defined(UNDER_CE) 224370b324cSopenharmony_ci else if (NWindows::NFile::NName::IsDrivePath2(parts[0])) 225370b324cSopenharmony_ci { 226370b324cSopenharmony_ci isDrive = true; 227370b324cSopenharmony_ci i = 1; 228370b324cSopenharmony_ci } 229370b324cSopenharmony_ci 230370b324cSopenharmony_ci if (isDrive) 231370b324cSopenharmony_ci { 232370b324cSopenharmony_ci // we convert "c:name" to "c:\name", if absIsAllowed path. 233370b324cSopenharmony_ci UString &ds = parts[i - 1]; 234370b324cSopenharmony_ci if (ds.Len() > 2) 235370b324cSopenharmony_ci { 236370b324cSopenharmony_ci parts.Insert(i, ds.Ptr(2)); 237370b324cSopenharmony_ci ds.DeleteFrom(2); 238370b324cSopenharmony_ci } 239370b324cSopenharmony_ci } 240370b324cSopenharmony_ci #endif 241370b324cSopenharmony_ci } 242370b324cSopenharmony_ci 243370b324cSopenharmony_ci if (i != 0) 244370b324cSopenharmony_ci keepAndReplaceEmptyPrefixes = false; 245370b324cSopenharmony_ci 246370b324cSopenharmony_ci for (; i < parts.Size();) 247370b324cSopenharmony_ci { 248370b324cSopenharmony_ci UString &s = parts[i]; 249370b324cSopenharmony_ci 250370b324cSopenharmony_ci Correct_PathPart(s); 251370b324cSopenharmony_ci 252370b324cSopenharmony_ci if (s.IsEmpty()) 253370b324cSopenharmony_ci { 254370b324cSopenharmony_ci if (!keepAndReplaceEmptyPrefixes) 255370b324cSopenharmony_ci if (isDir || i != parts.Size() - 1) 256370b324cSopenharmony_ci { 257370b324cSopenharmony_ci parts.Delete(i); 258370b324cSopenharmony_ci continue; 259370b324cSopenharmony_ci } 260370b324cSopenharmony_ci s = k_EmptyReplaceName; 261370b324cSopenharmony_ci } 262370b324cSopenharmony_ci else 263370b324cSopenharmony_ci { 264370b324cSopenharmony_ci keepAndReplaceEmptyPrefixes = false; 265370b324cSopenharmony_ci #ifdef _WIN32 266370b324cSopenharmony_ci CorrectUnsupportedName(s); 267370b324cSopenharmony_ci #endif 268370b324cSopenharmony_ci } 269370b324cSopenharmony_ci 270370b324cSopenharmony_ci i++; 271370b324cSopenharmony_ci } 272370b324cSopenharmony_ci 273370b324cSopenharmony_ci if (!isDir) 274370b324cSopenharmony_ci { 275370b324cSopenharmony_ci if (parts.IsEmpty()) 276370b324cSopenharmony_ci parts.Add((UString)k_EmptyReplaceName); 277370b324cSopenharmony_ci else 278370b324cSopenharmony_ci { 279370b324cSopenharmony_ci UString &s = parts.Back(); 280370b324cSopenharmony_ci if (s.IsEmpty()) 281370b324cSopenharmony_ci s = k_EmptyReplaceName; 282370b324cSopenharmony_ci } 283370b324cSopenharmony_ci } 284370b324cSopenharmony_ci} 285370b324cSopenharmony_ci 286370b324cSopenharmony_ciUString MakePathFromParts(const UStringVector &parts) 287370b324cSopenharmony_ci{ 288370b324cSopenharmony_ci UString s; 289370b324cSopenharmony_ci FOR_VECTOR (i, parts) 290370b324cSopenharmony_ci { 291370b324cSopenharmony_ci if (i != 0) 292370b324cSopenharmony_ci s.Add_PathSepar(); 293370b324cSopenharmony_ci s += parts[i]; 294370b324cSopenharmony_ci } 295370b324cSopenharmony_ci return s; 296370b324cSopenharmony_ci} 297