Files
deskflow/src/lib/arch/win32/ArchFileWindows.cpp
2025-03-19 20:01:01 +00:00

149 lines
3.4 KiB
C++

/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "arch/win32/ArchFileWindows.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlobj.h>
#include <string.h>
#include <tchar.h>
//
// ArchFileWindows
//
ArchFileWindows::ArchFileWindows()
{
// do nothing
}
ArchFileWindows::~ArchFileWindows()
{
// do nothing
}
const char *ArchFileWindows::getBasename(const char *pathname)
{
if (pathname == NULL) {
return NULL;
}
// check for last slash
const char *basename = strrchr(pathname, '/');
if (basename != NULL) {
++basename;
} else {
basename = pathname;
}
// check for last backslash
const char *basename2 = strrchr(pathname, '\\');
if (basename2 != NULL && basename2 > basename) {
basename = basename2 + 1;
}
return basename;
}
std::string ArchFileWindows::getUserDirectory()
{
// try %HOMEPATH%
TCHAR dir[MAX_PATH];
DWORD size = sizeof(dir) / sizeof(TCHAR);
DWORD result = GetEnvironmentVariable(_T("HOMEPATH"), dir, size);
if (result != 0 && result <= size) {
// sanity check -- if dir doesn't appear to start with a
// drive letter and isn't a UNC name then don't use it
// FIXME -- allow UNC names
if (dir[0] != '\0' && (dir[1] == ':' || ((dir[0] == '\\' || dir[0] == '/') && (dir[1] == '\\' || dir[1] == '/')))) {
return dir;
}
}
// get the location of the personal files. that's as close to
// a home directory as we're likely to find.
ITEMIDLIST *idl;
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &idl))) {
TCHAR *path = NULL;
if (SHGetPathFromIDList(idl, dir)) {
DWORD attr = GetFileAttributes(dir);
if (attr != 0xffffffff && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
path = dir;
}
IMalloc *shalloc;
if (SUCCEEDED(SHGetMalloc(&shalloc))) {
shalloc->Free(idl);
shalloc->Release();
}
if (path != NULL) {
return path;
}
}
// use root of C drive as a default
return "C:";
}
std::string ArchFileWindows::getSystemDirectory()
{
// get windows directory
char dir[MAX_PATH];
if (GetWindowsDirectory(dir, sizeof(dir)) != 0) {
return dir;
} else {
// can't get it. use C:\ as a default.
return "C:";
}
}
std::string ArchFileWindows::getInstalledDirectory()
{
char fileNameBuffer[MAX_PATH];
GetModuleFileName(NULL, fileNameBuffer, MAX_PATH);
std::string fileName(fileNameBuffer);
size_t lastSlash = fileName.find_last_of("\\");
fileName = fileName.substr(0, lastSlash);
return fileName;
}
std::string ArchFileWindows::getProfileDirectory()
{
std::string dir;
if (!m_profileDirectory.empty()) {
dir = m_profileDirectory;
} else {
TCHAR result[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, result))) {
dir = result;
} else {
dir = getUserDirectory();
}
}
return dir;
}
std::string ArchFileWindows::concatPath(const std::string &prefix, const std::string &suffix)
{
std::string path;
path.reserve(prefix.size() + 1 + suffix.size());
path += prefix;
if (path.size() == 0 || (path[path.size() - 1] != '\\' && path[path.size() - 1] != '/')) {
path += '\\';
}
path += suffix;
return path;
}
void ArchFileWindows::setProfileDirectory(const std::string &s)
{
m_profileDirectory = s;
}