Beispiel #1
0
std::string& GetExeDirectory()
{
  static std::string DolphinPath;
  if (DolphinPath.empty())
  {
#ifdef _WIN32
    TCHAR Dolphin_exe_Path[2048];
    TCHAR Dolphin_exe_Clean_Path[MAX_PATH];
    GetModuleFileName(nullptr, Dolphin_exe_Path, 2048);
    if (_tfullpath(Dolphin_exe_Clean_Path, Dolphin_exe_Path, MAX_PATH) != nullptr)
      DolphinPath = TStrToUTF8(Dolphin_exe_Clean_Path);
    else
      DolphinPath = TStrToUTF8(Dolphin_exe_Path);
    DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\'));
#else
    char Dolphin_exe_Path[PATH_MAX];
    ssize_t len = ::readlink("/proc/self/exe", Dolphin_exe_Path, sizeof(Dolphin_exe_Path));
    if (len == -1 || len == sizeof(Dolphin_exe_Path))
    {
      len = 0;
    }
    Dolphin_exe_Path[len] = '\0';
    DolphinPath = Dolphin_exe_Path;
    DolphinPath = DolphinPath.substr(0, DolphinPath.rfind('/'));
#endif
  }
  return DolphinPath;
}
Beispiel #2
0
std::string CreateTempDir()
{
#ifdef _WIN32
  TCHAR temp[MAX_PATH];
  if (!GetTempPath(MAX_PATH, temp))
    return "";

  GUID guid;
  CoCreateGuid(&guid);
  TCHAR tguid[40];
  StringFromGUID2(guid, tguid, 39);
  tguid[39] = 0;
  std::string dir = TStrToUTF8(temp) + "/" + TStrToUTF8(tguid);
  if (!CreateDir(dir))
    return "";
  dir = ReplaceAll(dir, "\\", DIR_SEP);
  return dir;
#else
  const char* base = getenv("TMPDIR") ?: "/tmp";
  std::string path = std::string(base) + "/DolphinWii.XXXXXX";
  if (!mkdtemp(&path[0]))
    return "";
  return path;
#endif
}
Beispiel #3
0
std::string GetExePath()
{
  static std::string dolphin_path;
  if (dolphin_path.empty())
  {
#ifdef _WIN32
    TCHAR dolphin_exe_path[2048];
    TCHAR dolphin_exe_expanded_path[MAX_PATH];
    GetModuleFileName(nullptr, dolphin_exe_path, ARRAYSIZE(dolphin_exe_path));
    if (_tfullpath(dolphin_exe_expanded_path, dolphin_exe_path,
                   ARRAYSIZE(dolphin_exe_expanded_path)) != nullptr)
      dolphin_path = TStrToUTF8(dolphin_exe_expanded_path);
    else
      dolphin_path = TStrToUTF8(dolphin_exe_path);
#elif defined(__APPLE__)
    dolphin_path = GetBundleDirectory();
    dolphin_path = dolphin_path.substr(0, dolphin_path.find_last_of("Dolphin.app/Contents/MacOS"));
#else
    char dolphin_exe_path[PATH_MAX];
    ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path));
    if (len == -1 || len == sizeof(dolphin_exe_path))
    {
      len = 0;
    }
    dolphin_exe_path[len] = '\0';
    dolphin_path = dolphin_exe_path;
#endif
  }
  return dolphin_path;
}
Beispiel #4
0
void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack)
{
	TCHAR symInfo[BUFFERSIZE] = _T("?");
	TCHAR srcInfo[BUFFERSIZE] = _T("?");

	GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo);
	GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo);
	etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n");
}
Beispiel #5
0
// Create directory and copy contents (does not overwrite existing files)
void CopyDir(const std::string& source_path, const std::string& dest_path, bool destructive)
{
  if (source_path == dest_path)
    return;
  if (!Exists(source_path))
    return;
  if (!Exists(dest_path))
    File::CreateFullPath(dest_path);

#ifdef _WIN32
  WIN32_FIND_DATA ffd;
  HANDLE hFind = FindFirstFile(UTF8ToTStr(source_path + "\\*").c_str(), &ffd);

  if (hFind == INVALID_HANDLE_VALUE)
  {
    FindClose(hFind);
    return;
  }

  do
  {
    const std::string virtualName(TStrToUTF8(ffd.cFileName));
#else
  DIR* dirp = opendir(source_path.c_str());
  if (!dirp)
    return;

  while (dirent* result = readdir(dirp))
  {
    const std::string virtualName(result->d_name);
#endif
    // check for "." and ".."
    if (virtualName == "." || virtualName == "..")
      continue;

    std::string source = source_path + DIR_SEP + virtualName;
    std::string dest = dest_path + DIR_SEP + virtualName;
    if (IsDirectory(source))
    {
      if (!Exists(dest))
        File::CreateFullPath(dest + DIR_SEP);
      CopyDir(source, dest, destructive);
    }
    else if (!destructive && !Exists(dest))
    {
      Copy(source, dest);
    }
    else if (destructive)
    {
      Rename(source, dest);
    }
#ifdef _WIN32
  } while (FindNextFile(hFind, &ffd) != 0);
  FindClose(hFind);
#else
  }
  closedir(dirp);
#endif
}
Beispiel #6
0
// Connect to a Wiimote with a known device path.
bool WiimoteWindows::ConnectInternal()
{
  if (IsConnected())
    return true;

  if (!IsNewWiimote(UTF16ToUTF8(m_devicepath)))
    return false;

  auto const open_flags = FILE_SHARE_READ | FILE_SHARE_WRITE;

  m_dev_handle = CreateFile(m_devicepath.c_str(), GENERIC_READ | GENERIC_WRITE, open_flags, nullptr,
                            OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);

  if (m_dev_handle == INVALID_HANDLE_VALUE)
  {
    m_dev_handle = nullptr;
    return false;
  }

#if 0
	TCHAR name[128] = {};
	pHidD_GetProductString(dev_handle, name, 128);

	//ERROR_LOG(WIIMOTE, "Product string: %s", TStrToUTF8(name).c_str());

	if (!IsValidBluetoothName(TStrToUTF8(name)))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

#if 0
	HIDD_ATTRIBUTES attr;
	attr.Size = sizeof(attr);
	if (!pHidD_GetAttributes(dev_handle, &attr))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

  // TODO: thread isn't started here now, do this elsewhere
  // This isn't as drastic as it sounds, since the process in which the threads
  // reside is normal priority. Needed for keeping audio reports at a decent rate
  /*
    if (!SetThreadPriority(m_wiimote_thread.native_handle(), THREAD_PRIORITY_TIME_CRITICAL))
    {
      ERROR_LOG(WIIMOTE, "Failed to set Wiimote thread priority");
    }
  */

  return true;
}
Beispiel #7
0
std::string& GetExeDirectory()
{
	static std::string DolphinPath;
	if (DolphinPath.empty())
	{
		TCHAR Dolphin_exe_Path[2048];
		GetModuleFileName(NULL, Dolphin_exe_Path, 2048);
		DolphinPath = TStrToUTF8(Dolphin_exe_Path);
		DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\'));
	}
	return DolphinPath;
}
Beispiel #8
0
// Create directory and copy contents (does not overwrite existing files)
void CopyDir(const std::string &source_path, const std::string &dest_path)
{
    if (source_path == dest_path) return;
    if (!File::Exists(source_path)) return;
    if (!File::Exists(dest_path)) File::CreateFullPath(dest_path);

#ifdef _WIN32
    WIN32_FIND_DATA ffd;
    HANDLE hFind = FindFirstFile(UTF8ToTStr(source_path + "\\*").c_str(), &ffd);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        FindClose(hFind);
        return;
    }

    do
    {
        const std::string virtualName(TStrToUTF8(ffd.cFileName));
#else
    struct dirent dirent, *result = NULL;
    DIR *dirp = opendir(source_path.c_str());
    if (!dirp) return;

    while (!readdir_r(dirp, &dirent, &result) && result)
    {
        const std::string virtualName(result->d_name);
#endif
        // check for "." and ".."
        if (virtualName == "." || virtualName == "..")
            continue;

        std::string source, dest;
        source = source_path + virtualName;
        dest = dest_path + virtualName;
        if (IsDirectory(source))
        {
            source += '/';
            dest += '/';
            if (!File::Exists(dest)) File::CreateFullPath(dest);
            CopyDir(source, dest);
        }
        else if (!File::Exists(dest)) File::Copy(source, dest);
#ifdef _WIN32
    }
    while (FindNextFile(hFind, &ffd) != 0);
    FindClose(hFind);
#else
    }
    closedir(dirp);
#endif
}
Beispiel #9
0
std::string GetTempFilenameForAtomicWrite(const std::string &path)
{
	std::string abs = path;
#ifdef _WIN32
	TCHAR absbuf[MAX_PATH];
	if (_tfullpath(absbuf, UTF8ToTStr(path).c_str(), MAX_PATH) != nullptr)
		abs = TStrToUTF8(absbuf);
#else
	char absbuf[PATH_MAX];
	if (realpath(path.c_str(), absbuf) != nullptr)
		abs = absbuf;
#endif
	return abs + ".xxx";
}
Beispiel #10
0
// Returns a vector with the device names
std::vector<std::string> cdio_get_devices()
{
    std::vector<std::string> drives;

    const DWORD buffsize = GetLogicalDriveStrings(0, nullptr);
    std::vector<TCHAR> buff(buffsize);
    if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1)
    {
        auto drive = buff.data();
        while (*drive)
        {
            if (is_cdrom(drive))
            {
                std::string str(TStrToUTF8(drive));
                str.pop_back(); // we don't want the final backslash
                drives.push_back(std::move(str));
            }

            // advance to next drive
            while (*drive++) {}
        }
    }
    return drives;
}
Beispiel #11
0
// Deletes the given directory and anything under it. Returns true on success.
bool DeleteDirRecursively(const std::string &directory)
{
	INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str());
#ifdef _WIN32
	// Find the first file in the directory.
	WIN32_FIND_DATA ffd;
	HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd);

	if (hFind == INVALID_HANDLE_VALUE)
	{
		FindClose(hFind);
		return false;
	}

	// windows loop
	do
	{
		const std::string virtualName(TStrToUTF8(ffd.cFileName));
#else
	struct dirent dirent, *result = NULL;
	DIR *dirp = opendir(directory.c_str());
	if (!dirp)
		return false;

	// non windows loop
	while (!readdir_r(dirp, &dirent, &result) && result)
	{
		const std::string virtualName = result->d_name;
#endif

		// check for "." and ".."
		if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
			((virtualName[0] == '.') && (virtualName[1] == '.') && 
			 (virtualName[2] == '\0')))
			continue;

		std::string newPath = directory + DIR_SEP_CHR + virtualName;
		if (IsDirectory(newPath))
		{
			if (!DeleteDirRecursively(newPath))
			{
				#ifndef _WIN32
				closedir(dirp);
				#endif

				return false;
			}
		}
		else
		{
			if (!File::Delete(newPath))
			{
				#ifndef _WIN32
				closedir(dirp);
				#endif

				return false;
			}
		}

#ifdef _WIN32
	} while (FindNextFile(hFind, &ffd) != 0);
	FindClose(hFind);
#else
	}
	closedir(dirp);
#endif
	File::DeleteDir(directory);
		
	return true;
}
Beispiel #12
0
// Scans the directory tree gets, starting from _Directory and adds the
// results into parentEntry. Returns the number of files+directories found
u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry)
{
	INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str());
	// How many files + directories we found
	u32 foundEntries = 0;
#ifdef _WIN32
	// Find the first file in the directory.
	WIN32_FIND_DATA ffd;

	HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		FindClose(hFind);
		return foundEntries;
	}
	// windows loop
	do
	{
		FSTEntry entry;
		const std::string virtualName(TStrToUTF8(ffd.cFileName));
#else
	struct dirent dirent, *result = NULL;

	DIR *dirp = opendir(directory.c_str());
	if (!dirp)
		return 0;

	// non windows loop
	while (!readdir_r(dirp, &dirent, &result) && result)
	{
		FSTEntry entry;
		const std::string virtualName(result->d_name);
#endif
		// check for "." and ".."
		if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
				((virtualName[0] == '.') && (virtualName[1] == '.') && 
				 (virtualName[2] == '\0')))
			continue;
		entry.virtualName = virtualName;
		entry.physicalName = directory;
		entry.physicalName += DIR_SEP + entry.virtualName;

		if (IsDirectory(entry.physicalName.c_str()))
		{
			entry.isDirectory = true;
			// is a directory, lets go inside
			entry.size = ScanDirectoryTree(entry.physicalName, entry);
			foundEntries += (u32)entry.size;
		}
		else
		{ // is a file 
			entry.isDirectory = false;
			entry.size = GetSize(entry.physicalName.c_str());
		}
		++foundEntries;
		// Push into the tree
		parentEntry.children.push_back(entry);		
#ifdef _WIN32 
	} while (FindNextFile(hFind, &ffd) != 0);
	FindClose(hFind);
#else
	}
	closedir(dirp);
#endif
	// Return number of entries found.
	return foundEntries;
}
Beispiel #13
0
void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath)
{
	std::string GCMSearchPath;
	BuildCompleteFilename(GCMSearchPath, _strPath, _searchString);
#ifdef _WIN32
	WIN32_FIND_DATA findData;
	HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData);

	if (FindFirst != INVALID_HANDLE_VALUE)
	{
		bool bkeepLooping = true;

		while (bkeepLooping)
		{
			if (findData.cFileName[0] != '.')
			{
				std::string strFilename;
				BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName));
				m_FileNames.push_back(strFilename);
			}

			bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false;
		}
	}
	FindClose(FindFirst);


#else
	// TODO: super lame/broken

	auto end_match(_searchString);

	// assuming we have a "*.blah"-like pattern
	if (!end_match.empty() && end_match[0] == '*')
		end_match.erase(0, 1);

	// ugly
	if (end_match == ".*")
		end_match.clear();

	DIR* dir = opendir(_strPath.c_str());

	if (!dir)
		return;

	while (auto const dp = readdir(dir))
	{
		std::string found(dp->d_name);

		if ((found != ".") && (found != "..") &&
		    (found.size() >= end_match.size()) &&
		    std::equal(end_match.rbegin(), end_match.rend(), found.rbegin()))
		{
			std::string full_name;
			if (_strPath.c_str()[_strPath.size() - 1] == DIR_SEP_CHR)
				full_name = _strPath + found;
			else
				full_name = _strPath + DIR_SEP + found;

			m_FileNames.push_back(full_name);
		}
	}

	closedir(dir);
#endif
}
Beispiel #14
0
void SetUserDirectory(const std::string& custom_path)
{
	if (!custom_path.empty())
	{
		File::CreateFullPath(custom_path + DIR_SEP);
		File::SetUserPath(D_USER_IDX, custom_path + DIR_SEP);
		return;
	}

	std::string user_path = "";
#ifdef _WIN32
	// Detect where the User directory is. There are five different cases (on top of the
	// command line flag, which overrides all this):
	// 1. GetExeDirectory()\portable.txt exists
	//    -> Use GetExeDirectory()\User
	// 2. HKCU\Software\Dolphin Emulator\LocalUserConfig exists and is true
	//    -> Use GetExeDirectory()\User
	// 3. HKCU\Software\Dolphin Emulator\UserConfigPath exists
	//    -> Use this as the user directory path
	// 4. My Documents exists
	//    -> Use My Documents\Dolphin Emulator as the User directory path
	// 5. Default
	//    -> Use GetExeDirectory()\User

	// Check our registry keys
	HKEY hkey;
	DWORD local = 0;
	TCHAR configPath[MAX_PATH] = {0};
	if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
	{
		DWORD size = 4;
		if (RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr, reinterpret_cast<LPBYTE>(&local), &size) != ERROR_SUCCESS)
			local = 0;

		size = MAX_PATH;
		if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS)
			configPath[0] = 0;
		RegCloseKey(hkey);
	}

	local = local || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt");

	// Get Program Files path in case we need it.
	TCHAR my_documents[MAX_PATH];
	bool my_documents_found = SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents));

	if (local) // Case 1-2
		user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
	else if (configPath[0]) // Case 3
		user_path = TStrToUTF8(configPath);
	else if (my_documents_found) // Case 4
		user_path = TStrToUTF8(my_documents) + DIR_SEP "Dolphin Emulator" DIR_SEP;
	else // Case 5
		user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;

	// Prettify the path: it will be displayed in some places, we don't want a mix of \ and /.
	user_path = ReplaceAll(user_path, "\\", DIR_SEP);

	// Make sure it ends in DIR_SEP.
	if (*user_path.rbegin() != DIR_SEP_CHR)
		user_path += DIR_SEP;
#else
	if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR))
	{
		user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
	}
	else
	{
		const char* home = getenv("HOME");
		if (!home)
			home = getenv("PWD");
		if (!home)
			home = "";
		std::string home_path = std::string(home) + DIR_SEP;

#if defined(__APPLE__) || defined(ANDROID)
		user_path = home_path + DOLPHIN_DATA_DIR DIR_SEP;
#else
		// We are on a non-Apple and non-Android POSIX system, let's respect XDG basedir.
		// The only case we don't is when there is an existing ~/.dolphin-emu directory.
		// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

		user_path = home_path + "." DOLPHIN_DATA_DIR DIR_SEP;
		if (!File::Exists(user_path))
		{
			const char* data_home = getenv("XDG_DATA_HOME");
			std::string data_path = std::string(data_home && data_home[0] == '/' ?
				data_home :
				(home_path + ".local" DIR_SEP "share")) + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP;

			const char* config_home = getenv("XDG_CONFIG_HOME");
			std::string config_path = std::string(config_home && config_home[0] == '/' ?
				config_home :
				(home_path + ".config")) + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP;

			const char* cache_home = getenv("XDG_CACHE_HOME");
			std::string cache_path = std::string(cache_home && cache_home[0] == '/' ?
				cache_home :
				(home_path + ".cache")) + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP;

			File::SetUserPath(D_USER_IDX, data_path);
			File::SetUserPath(D_CONFIG_IDX, config_path);
			File::SetUserPath(D_CACHE_IDX, cache_path);
			return;
		}
#endif
	}
#endif
	File::SetUserPath(D_USER_IDX, user_path);
}
Beispiel #15
0
// Recursive or non-recursive list of files and directories under directory.
FSTEntry ScanDirectoryTree(const std::string& directory, bool recursive)
{
  INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str());
  FSTEntry parent_entry;
  parent_entry.physicalName = directory;
  parent_entry.isDirectory = true;
  parent_entry.size = 0;
#ifdef _WIN32
  // Find the first file in the directory.
  WIN32_FIND_DATA ffd;

  HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
  {
    FindClose(hFind);
    return parent_entry;
  }
  // Windows loop
  do
  {
    const std::string virtual_name(TStrToUTF8(ffd.cFileName));
#else
  DIR* dirp = opendir(directory.c_str());
  if (!dirp)
    return parent_entry;

  // non Windows loop
  while (dirent* result = readdir(dirp))
  {
    const std::string virtual_name(result->d_name);
#endif
    if (virtual_name == "." || virtual_name == "..")
      continue;
    auto physical_name = directory + DIR_SEP + virtual_name;
    FSTEntry entry;
    const FileInfo file_info(physical_name);
    entry.isDirectory = file_info.IsDirectory();
    if (entry.isDirectory)
    {
      if (recursive)
        entry = ScanDirectoryTree(physical_name, true);
      else
        entry.size = 0;
      parent_entry.size += entry.size;
    }
    else
    {
      entry.size = file_info.GetSize();
    }
    entry.virtualName = virtual_name;
    entry.physicalName = physical_name;

    ++parent_entry.size;
    // Push into the tree
    parent_entry.children.push_back(entry);
#ifdef _WIN32
  } while (FindNextFile(hFind, &ffd) != 0);
  FindClose(hFind);
#else
  }
  closedir(dirp);
#endif

  return parent_entry;
}
Beispiel #16
0
// Returns a string with a Dolphin data dir or file in the user's home
// directory. To be used in "multi-user" mode (that is, installed).
const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath)
{
	static std::string paths[NUM_PATH_INDICES];

	// Set up all paths and files on the first run
	if (paths[D_USER_IDX].empty())
	{
#ifdef _WIN32
		// Detect where the User directory is. There are five different cases (on top of the
		// command line flag, which overrides all this):
		// 1. GetExeDirectory()\portable.txt exists
		//    -> Use GetExeDirectory()\User
		// 2. HKCU\Software\Dolphin Emulator\LocalUserConfig exists and is true
		//    -> Use GetExeDirectory()\User
		// 3. HKCU\Software\Dolphin Emulator\UserConfigPath exists
		//    -> Use this as the user directory path
		// 4. My Documents exists
		//    -> Use My Documents\Dolphin Emulator as the User directory path
		// 5. Default
		//    -> Use GetExeDirectory()\User

		// Check our registry keys
		HKEY hkey;
		DWORD local = 0;
		TCHAR configPath[MAX_PATH] = {0};
		if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
		{
			DWORD size = 4;
			if (RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr, reinterpret_cast<LPBYTE>(&local), &size) != ERROR_SUCCESS)
				local = 0;

			size = MAX_PATH;
			if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS)
				configPath[0] = 0;
			RegCloseKey(hkey);
		}

		local = local || File::Exists(GetExeDirectory() + DIR_SEP "portable.txt");

		// Get Program Files path in case we need it.
		TCHAR my_documents[MAX_PATH];
		bool my_documents_found = SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents));

		if (local) // Case 1-2
			paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
		else if (configPath[0]) // Case 3
			paths[D_USER_IDX] = TStrToUTF8(configPath);
		else if (my_documents_found) // Case 4
			paths[D_USER_IDX] = TStrToUTF8(my_documents) + DIR_SEP "Dolphin Emulator" DIR_SEP;
		else // Case 5
			paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;

		// Prettify the path: it will be displayed in some places, we don't want a mix of \ and /.
		paths[D_USER_IDX] = ReplaceAll(paths[D_USER_IDX], "\\", DIR_SEP);

		// Make sure it ends in DIR_SEP.
		if (*paths[D_USER_IDX].rbegin() != DIR_SEP_CHR)
			paths[D_USER_IDX] += DIR_SEP;
#else
		if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR))
			paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
		else
			paths[D_USER_IDX] = std::string(getenv("HOME") ?
				getenv("HOME") : getenv("PWD") ?
				getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP;
#endif

		paths[D_GCUSER_IDX]         = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP;
		paths[D_WIIROOT_IDX]        = paths[D_USER_IDX] + WII_USER_DIR;
		paths[D_WIIUSER_IDX]        = paths[D_WIIROOT_IDX] + DIR_SEP;
		paths[D_CONFIG_IDX]         = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
		paths[D_GAMESETTINGS_IDX]   = paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP;
		paths[D_MAPS_IDX]           = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
		paths[D_CACHE_IDX]          = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
		paths[D_SHADERCACHE_IDX]    = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
		paths[D_SHADERS_IDX]        = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
		paths[D_STATESAVES_IDX]     = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
		paths[D_SCREENSHOTS_IDX]    = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
		paths[D_HIRESTEXTURES_IDX]  = paths[D_USER_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
		paths[D_DUMP_IDX]           = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
		paths[D_DUMPFRAMES_IDX]     = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
		paths[D_DUMPAUDIO_IDX]      = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
		paths[D_DUMPTEXTURES_IDX]   = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
		paths[D_DUMPDSP_IDX]        = paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
		paths[D_LOGS_IDX]           = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
		paths[D_MAILLOGS_IDX]       = paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
		paths[D_WIISYSCONF_IDX]     = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP;
		paths[D_WIIWC24_IDX]        = paths[D_WIIUSER_IDX] + WII_WC24CONF_DIR DIR_SEP;
		paths[D_THEMES_IDX]         = paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
		paths[F_DOLPHINCONFIG_IDX]  = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
		paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
		paths[F_LOGGERCONFIG_IDX]   = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
		paths[F_MAINLOG_IDX]        = paths[D_LOGS_IDX] + MAIN_LOG;
		paths[F_WIISYSCONF_IDX]     = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
		paths[F_RAMDUMP_IDX]        = paths[D_DUMP_IDX] + RAM_DUMP;
		paths[F_ARAMDUMP_IDX]       = paths[D_DUMP_IDX] + ARAM_DUMP;
		paths[F_FAKEVMEMDUMP_IDX]   = paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
		paths[F_GCSRAM_IDX]         = paths[D_GCUSER_IDX] + GC_SRAM;
	}

	if (!newPath.empty())
	{
		if (!File::IsDirectory(newPath))
		{
			WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str());
			return paths[DirIDX];
		}
		else
		{
			paths[DirIDX] = newPath;
		}

		switch (DirIDX)
		{
		case D_WIIROOT_IDX:
			paths[D_WIIUSER_IDX]    = paths[D_WIIROOT_IDX] + DIR_SEP;
			paths[D_WIISYSCONF_IDX] = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR + DIR_SEP;
			paths[F_WIISYSCONF_IDX] = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
			break;

		case D_USER_IDX:
			paths[D_GCUSER_IDX]         = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP;
			paths[D_WIIROOT_IDX]        = paths[D_USER_IDX] + WII_USER_DIR;
			paths[D_WIIUSER_IDX]        = paths[D_WIIROOT_IDX] + DIR_SEP;
			paths[D_CONFIG_IDX]         = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
			paths[D_GAMESETTINGS_IDX]   = paths[D_USER_IDX] + GAMESETTINGS_DIR DIR_SEP;
			paths[D_MAPS_IDX]           = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
			paths[D_CACHE_IDX]          = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
			paths[D_SHADERCACHE_IDX]    = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
			paths[D_SHADERS_IDX]        = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
			paths[D_STATESAVES_IDX]     = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
			paths[D_SCREENSHOTS_IDX]    = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
			paths[D_HIRESTEXTURES_IDX]  = paths[D_USER_IDX] + HIRES_TEXTURES_DIR DIR_SEP;
			paths[D_DUMP_IDX]           = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
			paths[D_DUMPFRAMES_IDX]     = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
			paths[D_DUMPAUDIO_IDX]      = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
			paths[D_DUMPTEXTURES_IDX]   = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
			paths[D_DUMPDSP_IDX]        = paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
			paths[D_LOGS_IDX]           = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
			paths[D_MAILLOGS_IDX]       = paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
			paths[D_WIISYSCONF_IDX]     = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP;
			paths[D_THEMES_IDX]         = paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
			paths[F_DOLPHINCONFIG_IDX]  = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
			paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
			paths[F_LOGGERCONFIG_IDX]   = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
			paths[F_MAINLOG_IDX]        = paths[D_LOGS_IDX] + MAIN_LOG;
			paths[F_WIISYSCONF_IDX]     = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
			paths[F_RAMDUMP_IDX]        = paths[D_DUMP_IDX] + RAM_DUMP;
			paths[F_ARAMDUMP_IDX]       = paths[D_DUMP_IDX] + ARAM_DUMP;
			paths[F_FAKEVMEMDUMP_IDX]   = paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
			paths[F_GCSRAM_IDX]         = paths[D_GCUSER_IDX] + GC_SRAM;
			break;

		case D_CONFIG_IDX:
			paths[F_DOLPHINCONFIG_IDX]  = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
			paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
			paths[F_LOGGERCONFIG_IDX]   = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
			break;

		case D_GCUSER_IDX:
			paths[F_GCSRAM_IDX]         = paths[D_GCUSER_IDX] + GC_SRAM;
			break;

		case D_DUMP_IDX:
			paths[D_DUMPFRAMES_IDX]     = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
			paths[D_DUMPAUDIO_IDX]      = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
			paths[D_DUMPTEXTURES_IDX]   = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
			paths[D_DUMPDSP_IDX]        = paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
			paths[F_RAMDUMP_IDX]        = paths[D_DUMP_IDX] + RAM_DUMP;
			paths[F_ARAMDUMP_IDX]       = paths[D_DUMP_IDX] + ARAM_DUMP;
			paths[F_FAKEVMEMDUMP_IDX]   = paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
			break;
		case D_LOGS_IDX:
			paths[D_MAILLOGS_IDX]       = paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
			paths[F_MAINLOG_IDX]        = paths[D_LOGS_IDX] + MAIN_LOG;
		}

		paths[D_WIIUSER_IDX]    = paths[D_WIIROOT_IDX] + DIR_SEP;
		paths[D_WIIWC24_IDX]    = paths[D_WIIUSER_IDX] + WII_WC24CONF_DIR DIR_SEP;
		paths[D_WIISYSCONF_IDX] = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR + DIR_SEP;
		paths[F_WIISYSCONF_IDX] = paths[D_WIISYSCONF_IDX] + WII_SYSCONF;
	}

	return paths[DirIDX];
}
Beispiel #17
0
// Connect to a Wiimote with a known device path.
bool WiimoteWindows::ConnectInternal()
{
	if (IsConnected())
		return false;

#ifdef SHARE_WRITE_WIIMOTES
	std::lock_guard<std::mutex> lk(g_connected_wiimotes_lock);
	if (g_connected_wiimotes.count(m_devicepath) != 0)
		return false;

	auto const open_flags = FILE_SHARE_READ | FILE_SHARE_WRITE;
#else
	// Having no FILE_SHARE_WRITE disallows us from connecting to the same Wiimote twice.
	// (And disallows using Wiimotes in use by other programs)
	// This is what "WiiYourself" does.
	// Apparently this doesn't work for everyone. It might be their fault.
	auto const open_flags = FILE_SHARE_READ;
#endif

	m_dev_handle = CreateFile(m_devicepath.c_str(),
		GENERIC_READ | GENERIC_WRITE, open_flags,
		nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);

	if (m_dev_handle == INVALID_HANDLE_VALUE)
	{
		m_dev_handle = 0;
		return false;
	}

#if 0
	TCHAR name[128] = {};
	pHidD_GetProductString(dev_handle, name, 128);

	//ERROR_LOG(WIIMOTE, "Product string: %s", TStrToUTF8(name).c_str());

	if (!IsValidBluetoothName(TStrToUTF8(name)))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

#if 0
	HIDD_ATTRIBUTES attr;
	attr.Size = sizeof(attr);
	if (!pHidD_GetAttributes(dev_handle, &attr))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

	// TODO: thread isn't started here now, do this elsewhere
	// This isn't as drastic as it sounds, since the process in which the threads
	// reside is normal priority. Needed for keeping audio reports at a decent rate
/*
	if (!SetThreadPriority(m_wiimote_thread.native_handle(), THREAD_PRIORITY_TIME_CRITICAL))
	{
		ERROR_LOG(WIIMOTE, "Failed to set Wiimote thread priority");
	}
*/
#ifdef SHARE_WRITE_WIIMOTES
	g_connected_wiimotes.insert(m_devicepath);
#endif

	return true;
}