chromium/third_party/unrar/src/pathfn.cpp

#include "rar.hpp"

wchar* PointToName(const wchar *Path)
{}


std::wstring PointToName(const std::wstring &Path)
{}


size_t GetNamePos(const std::wstring &Path)
{}


wchar* PointToLastChar(const wchar *Path)
{}


wchar GetLastChar(const std::wstring &Path)
{}


size_t ConvertPath(const std::wstring *SrcPath,std::wstring *DestPath)
{}


void SetName(std::wstring &FullName,const std::wstring &Name)
{}


void SetExt(std::wstring &Name,std::wstring NewExt)
{}


// Unlike SetExt(Name,L""), it removes the trailing dot too.
void RemoveExt(std::wstring &Name)
{}


#ifndef SFX_MODULE
void SetSFXExt(std::wstring &SFXName)
{}
#endif


// 'Ext' is an extension with the leading dot, like L".rar".
wchar *GetExt(const wchar *Name)
{}


// 'Ext' is an extension with the leading dot, like L".rar", or empty string
// if extension is missing.
std::wstring GetExt(const std::wstring &Name)
{}


// Returns the position of extension leading dot or std::wstring::npos
// if extension is not present.
std::wstring::size_type GetExtPos(const std::wstring &Name)
{}


// 'Ext' is an extension without the leading dot, like L"rar".
bool CmpExt(const std::wstring &Name,const std::wstring &Ext)
{}


bool IsWildcard(const std::wstring &Str)
{}


bool IsPathDiv(int Ch)
{}


bool IsDriveDiv(int Ch)
{}


bool IsDriveLetter(const std::wstring &Path)
{}


int GetPathDisk(const std::wstring &Path)
{}


void AddEndSlash(std::wstring &Path)
{}


void MakeName(const std::wstring &Path,const std::wstring &Name,std::wstring &Pathname)
{}


// Returns the file path including the trailing path separator symbol.
// It is allowed for both parameters to point to the same string.
void GetPathWithSep(const std::wstring &FullName,std::wstring &Path)
{}


// Removes name and returns file path without the trailing path separator.
// But for names like d:\name return d:\ with trailing path separator.
void RemoveNameFromPath(std::wstring &Path)
{}


#if defined(_WIN_ALL) && !defined(SFX_MODULE)
bool GetAppDataPath(std::wstring &Path,bool Create)
{
  LPMALLOC g_pMalloc;
  SHGetMalloc(&g_pMalloc);
  LPITEMIDLIST ppidl;
  Path.clear();
  bool Success=false;
  if (SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA,&ppidl)==NOERROR &&
      SHGetPathStrFromIDList(ppidl,Path) && !Path.empty())
  {
    AddEndSlash(Path);
    Path+=L"WinRAR";
    Success=FileExist(Path);
    if (!Success && Create)
      Success=CreateDir(Path);
  }
  g_pMalloc->Free(ppidl);
  return Success;
}
#endif


#if defined(_WIN_ALL)
bool SHGetPathStrFromIDList(PCIDLIST_ABSOLUTE pidl,std::wstring &Path)
{
  std::vector<wchar> Buf(MAX_PATH);
  bool Success=SHGetPathFromIDList(pidl,Buf.data())!=FALSE;
  Path=Buf.data();
  return Success;
}
#endif


#if defined(_WIN_ALL) && !defined(SFX_MODULE)
void GetRarDataPath(std::wstring &Path,bool Create)
{
  Path.clear();

  HKEY hKey;
  if (RegOpenKeyEx(HKEY_CURRENT_USER,L"Software\\WinRAR\\Paths",0,
                   KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS)
  {
    DWORD DataSize;
    LSTATUS Code=RegQueryValueEx(hKey,L"AppData",NULL,NULL,NULL,&DataSize);
    if (Code==ERROR_SUCCESS)
    {
      std::vector<wchar> PathBuf(DataSize/sizeof(wchar));
      RegQueryValueEx(hKey,L"AppData",0,NULL,(BYTE *)PathBuf.data(),&DataSize);
      Path=PathBuf.data();
      RegCloseKey(hKey);
    }
  }

  if (Path.empty() || !FileExist(Path))
    if (!GetAppDataPath(Path,Create))
    {
      Path=GetModuleFileStr();
      RemoveNameFromPath(Path);
    }
}
#endif


#ifndef SFX_MODULE
bool EnumConfigPaths(uint Number,std::wstring &Path,bool Create)
{}
#endif


#ifndef SFX_MODULE
void GetConfigName(const std::wstring &Name,std::wstring &FullName,bool CheckExist,bool Create)
{}
#endif


// Returns the position to rightmost digit of volume number or beginning
// of file name if numeric part is missing.
size_t GetVolNumPos(const std::wstring &ArcName)
{}


void NextVolumeName(std::wstring &ArcName,bool OldNumbering)
{}


bool IsNameUsable(const std::wstring &Name)
{}


void MakeNameUsable(std::wstring &Name,bool Extended)
{}


void UnixSlashToDos(const char *SrcName,char *DestName,size_t MaxLength)
{}


void UnixSlashToDos(const wchar *SrcName,wchar *DestName,size_t MaxLength)
{}


void UnixSlashToDos(const std::string &SrcName,std::string &DestName)
{}


void UnixSlashToDos(const std::wstring &SrcName,std::wstring &DestName)
{}


void DosSlashToUnix(const char *SrcName,char *DestName,size_t MaxLength)
{}


void DosSlashToUnix(const wchar *SrcName,wchar *DestName,size_t MaxLength)
{}


void DosSlashToUnix(const std::string &SrcName,std::string &DestName)
{}


void DosSlashToUnix(const std::wstring &SrcName,std::wstring &DestName)
{}


void ConvertNameToFull(const std::wstring &Src,std::wstring &Dest)
{}


bool IsFullPath(const std::wstring &Path)
{}


bool IsFullRootPath(const std::wstring &Path)
{}


// Both source and destination can point to the same string.
void GetPathRoot(const std::wstring &Path,std::wstring &Root)
{}


int ParseVersionFileName(std::wstring &Name,bool Truncate)
{}


#if !defined(SFX_MODULE)
// Get the name of first volume. Return the leftmost digit position of volume number.
size_t VolNameToFirstName(const std::wstring &VolName,std::wstring &FirstName,bool NewNumbering)
{}
#endif


#ifndef SFX_MODULE
static void GenArcName(std::wstring &ArcName,const std::wstring &GenerateMask,uint ArcNumber,bool &ArcNumPresent)
{}


void GenerateArchiveName(std::wstring &ArcName,const std::wstring &GenerateMask,bool Archiving)
{}
#endif


#ifdef _WIN_ALL
// We should return 'true' even if resulting path is shorter than MAX_PATH,
// because we can also use this function to open files with non-standard
// characters, even if their path length is normal.
bool GetWinLongPath(const std::wstring &Src,std::wstring &Dest)
{
  if (Src.empty())
    return false;
  const std::wstring Prefix=L"\\\\?\\";

  bool FullPath=Src.size()>=3 && IsDriveLetter(Src) && IsPathDiv(Src[2]);
  if (IsFullPath(Src)) // Paths in d:\path\name format.
  {
    if (IsDriveLetter(Src))
    {
      Dest=Prefix+Src; // "\\?\D:\very long path".
      return true;
    }
    else
      if (Src.size()>2 && Src[0]=='\\' && Src[1]=='\\')
      {
        Dest=Prefix+L"UNC"+Src.substr(1);  // "\\?\UNC\server\share".
        return true;
      }
    // We can be here only if modify IsFullPath() in the future.
    return false;
  }
  else
  {
    std::wstring CurDir;
    if (!GetCurDir(CurDir))
      return false;

    if (IsPathDiv(Src[0])) // Paths in \path\name format.
    {
      Dest=Prefix+CurDir[0]+L':'+Src;  // Copy drive letter 'd:'.
      return true;
    }
    else  // Paths in path\name format.
    {
      Dest=Prefix+CurDir;
      AddEndSlash(Dest);

      size_t Pos=0;
      if (Src[0]=='.' && IsPathDiv(Src[1])) // Remove leading .\ in pathname.
        Pos=2;

      Dest+=Src.substr(Pos);
      return true;
    }
  }
  return false;
}


// Convert Unix, OS X and Android decomposed chracters to Windows precomposed.
void ConvertToPrecomposed(std::wstring &Name)
{
  if (WinNT()<WNT_VISTA) // MAP_PRECOMPOSED is not supported in XP.
    return;
  int Size=FoldString(MAP_PRECOMPOSED,Name.c_str(),-1,NULL,0);
  if (Size<=0)
    return;
  std::vector<wchar> FileName(Size);
  if (FoldString(MAP_PRECOMPOSED,Name.c_str(),-1,FileName.data(),(int)FileName.size())!=0)
    Name=FileName.data();
}


void MakeNameCompatible(std::wstring &Name)
{
  // Remove trailing spaces and dots in file name and in dir names in path.
  for (int I=0;I<(int)Name.size();I++)
    if (I+1==Name.size() || IsPathDiv(Name[I+1]))
      while (I>=0 && (Name[I]=='.' || Name[I]==' '))
      {
        if (I==0 && Name[I]==' ')
        {
          // Windows 10 Explorer can't rename or delete " " files and folders.
          Name[I]='_'; // Convert " /path" to "_/path".
          break;
        }
        if (Name[I]=='.')
        {
          // 2024.05.01: Permit ./path1, path1/./path2, ../path1,
          // path1/../path2 and exotic Win32 d:.\path1, d:..\path1 paths
          // requested by user. Leading dots are possible here if specified
          // by user in the destination path.
          if (I==0 || IsPathDiv(Name[I-1]) || I==2 && IsDriveLetter(Name))
            break;
          if (I>=1 && Name[I-1]=='.' && (I==1 || IsPathDiv(Name[I-2]) ||
              I==3 && IsDriveLetter(Name)))
            break;
        }
        Name.erase(I,1);
        I--;
      }

  // Rename reserved device names, such as aux.txt to _aux.txt.
  // We check them in path components too, where they are also prohibited.
  for (size_t I=0;I<Name.size();I++)
    if (I==0 || I>0 && IsPathDiv(Name[I-1]))
    {
      static const wchar *Devices[]={L"CON",L"PRN",L"AUX",L"NUL",L"COM#",L"LPT#"};
      const wchar *s=&Name[I];
      bool MatchFound=false;
      for (uint J=0;J<ASIZE(Devices);J++)
        for (uint K=0;;K++)
          if (Devices[J][K]=='#')
          {
            if (!IsDigit(s[K]))
              break;
          }
          else
            if (Devices[J][K]==0)
            {
              // Names like aux.txt are accessible without \\?\ prefix
              // since Windows 11. Pure aux is still prohibited.
              MatchFound=s[K]==0 || s[K]=='.' && !IsWindows11OrGreater() || IsPathDiv(s[K]);
              break;
            }
            else
              if (Devices[J][K]!=toupperw(s[K]))
                break;
      if (MatchFound)
      {
        std::wstring OrigName=Name;
        Name.insert(I,1,'_');
#ifndef SFX_MODULE
        uiMsg(UIMSG_CORRECTINGNAME,nullptr);
        uiMsg(UIERROR_RENAMING,nullptr,OrigName,Name);
#endif
      }
    }
}
#endif




#ifdef _WIN_ALL
std::wstring GetModuleFileStr()
{
  HMODULE hModule=nullptr;
  
  std::vector<wchar> Path(256);
  while (Path.size()<=MAXPATHSIZE)
  {
    if (GetModuleFileName(hModule,Path.data(),(DWORD)Path.size())<Path.size())
      break;
    Path.resize(Path.size()*4);
  }
  return std::wstring(Path.data());
}


// Return the pathname of file in RAR or WinRAR folder.
// 'Name' can point to non-existent file and include wildcards.
std::wstring GetProgramFile(const std::wstring &Name)
{
  std::wstring FullName=GetModuleFileStr();
  SetName(FullName,Name);
  return FullName;
}
#endif


#if defined(_WIN_ALL)
bool SetCurDir(const std::wstring &Dir)
{
  return SetCurrentDirectory(Dir.c_str())!=0;
}
#endif


#ifdef _WIN_ALL
bool GetCurDir(std::wstring &Dir)
{
  DWORD BufSize=GetCurrentDirectory(0,NULL);
  if (BufSize==0)
    return false;
  std::vector<wchar> Buf(BufSize);
  DWORD Code=GetCurrentDirectory((DWORD)Buf.size(),Buf.data());
  Dir=Buf.data();
  return Code!=0;
}
#endif