Skip to content

Commit

Permalink
change get_special_folder for consistency & safety
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel committed Nov 20, 2023
1 parent 01ee2eb commit 5b37950
Showing 1 changed file with 39 additions and 38 deletions.
77 changes: 39 additions & 38 deletions third-party/rsutils/src/special-folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,43 @@ namespace rsutils {
namespace os {


std::string get_folder_path( special_folder f )
std::string get_special_folder( special_folder f )
{
std::string res;

#ifdef _WIN32


if( f == special_folder::temp_folder )
{
TCHAR buf[MAX_PATH];
if( GetTempPath( MAX_PATH, buf ) != 0 )
{
char str[1024];
wcstombs( str, buf, 1023 );
res = str;
}
char buf[MAX_PATH+2]; // "The maximum possible return value is MAX_PATH+1"
auto len = GetTempPathA( sizeof( buf ), buf ); // "return the length of the string, not including the terminating null character"
if( len > 0 ) // zero on failure
res.assign( buf, len );
else
throw std::runtime_error( "failed to get temp folder" );
}
else if( f == special_folder::user_documents )
{
// The user's Documents folder location may get overridden, as we know OneDrive does in certain
// circumstances. In such cases, the new function, SHGetKnownFolderPath, does not always return the new
// path, while the deprecated function does.
CHAR path[MAX_PATH];
CHECK_HR( SHGetFolderPathA( NULL, CSIDL_PERSONAL, NULL, 0, path ) );
res = path;
res += "\\";
}
else
{
GUID folder;
HRESULT hr;
switch( f )
{
case special_folder::user_desktop:
folder = FOLDERID_Desktop;
break;
case special_folder::user_documents:
folder = FOLDERID_Documents;
// The user's Documents folder location may get overridden, as we know OneDrive does in certain
// circumstances. In such cases, the new function, SHGetKnownFolderPath, does not always return the new
// path, while the deprecated function does.
CHAR path[MAX_PATH];
CHECK_HR( SHGetFolderPathA( NULL, CSIDL_PERSONAL, NULL, 0, path ) );
res = path;
res += "\\";
return res;
break;
case special_folder::user_pictures:
folder = FOLDERID_Pictures;
break;
Expand All @@ -68,29 +70,26 @@ std::string get_folder_path( special_folder f )
folder = FOLDERID_RoamingAppData;
break;
default:
throw std::invalid_argument( std::string( "Value of f (" ) + std::to_string( (int)f )
+ std::string( ") is not supported" ) );
throw std::invalid_argument( "special_folder value (" + std::to_string( (int)f ) + ") is not supported" );
}

PWSTR folder_path = NULL;
hr = SHGetKnownFolderPath( folder, KF_FLAG_DEFAULT_PATH, NULL, &folder_path );
if( SUCCEEDED( hr ) )
{
char str[1024];
wcstombs( str, folder_path, 1023 );
CoTaskMemFree( folder_path );
res = str;
res += "\\";
}
else
{
throw std::runtime_error( "Failed to get requested special folder" );
}
PWSTR path = NULL;
HRESULT hr = SHGetKnownFolderPath( folder, KF_FLAG_DEFAULT_PATH, NULL, &path );
CHECK_HR_STR( "SHGetKnownFolderPath", hr ); // throws runtime_error
char str[1024];
size_t len;
auto error = wcstombs_s( &len, str, path, 1023 );
CoTaskMemFree( path );
if( error )
throw std::runtime_error( "failed to convert special folder: errno=" + std::to_string( error ) );
res = str;
res += "\\";
}


#endif //_WIN32
#if defined __linux__ || defined __APPLE__
#elif defined __linux__ || defined __APPLE__


if( f == special_folder::temp_folder )
{
const char * tmp_dir = getenv( "TMPDIR" );
Expand All @@ -102,7 +101,10 @@ std::string get_folder_path( special_folder f )
if( ! home_dir )
{
struct passwd * pw = getpwuid( getuid() );
home_dir = ( pw && pw->pw_dir ) ? pw->pw_dir : "";
if( pw && pw->pw_dir )
home_dir = pw->pw_dir;
else
throw std::runtime_error( "failed to get special folder " + std::to_string( (int)f ) );
}
if( home_dir )
{
Expand All @@ -125,8 +127,7 @@ std::string get_folder_path( special_folder f )
res += "/.";
break;
default:
throw std::invalid_argument( std::string( "Value of f (" ) + std::to_string( (int)f )
+ std::string( ") is not supported" ) );
throw std::invalid_argument( "special_folder value (" + std::to_string( (int) f ) + ") is not supported" );
}
}
}
Expand Down

0 comments on commit 5b37950

Please sign in to comment.