Пример #1
0
/**
 * Default directory fallback is:
 *   - (command line argument)
 *   - <platform dependent>
 */
void platform_resolve_user_data_path()
{
	const char separator[2] = { platform_get_path_separator(), 0 };

	if (gCustomUserDataPath[0] != 0) {
		if (realpath(gCustomUserDataPath, _userDataDirectoryPath) == NULL) {
			log_error("Could not resolve path \"%s\"", gCustomUserDataPath);
			return;
		}

		// Ensure path ends with separator
		int len = strlen(_userDataDirectoryPath);
		if (_userDataDirectoryPath[len - 1] != separator[0]) {
			strncat(_userDataDirectoryPath, separator, MAX_PATH - 1);
		}
		return;
	}

	char buffer[MAX_PATH];
	buffer[0] = '\0';
	log_verbose("buffer = '%s'", buffer);

	const char *homedir = getpwuid(getuid())->pw_dir;
	platform_posix_sub_user_data_path(buffer, homedir, separator);

	log_verbose("OpenRCT2 user data directory = '%s'", buffer);
	int len = strnlen(buffer, MAX_PATH);
	wchar_t *w_buffer = regular_to_wchar(buffer);
	w_buffer[len] = '\0';
	utf8 *path = widechar_to_utf8(w_buffer);
	free(w_buffer);
	safe_strcpy(_userDataDirectoryPath, path, MAX_PATH);
	free(path);
}
Пример #2
0
/**
 * Default directory fallback is:
 *   - (command line argument)
 *   - $XDG_CONFIG_HOME/.config/OpenRCT2
 *   - /home/[uid]/.config/OpenRCT2
 */
void platform_resolve_user_data_path()
{
	const char separator[2] = { platform_get_path_separator(), 0 };

	if (gCustomUserDataPath[0] != 0) {
		realpath(gCustomUserDataPath, _userDataDirectoryPath);

		// Ensure path ends with separator
		int len = strlen(_userDataDirectoryPath);
		if (_userDataDirectoryPath[len - 1] != separator[0]) {
			strcat(_userDataDirectoryPath, separator);
		}
		return;
	}

	char buffer[MAX_PATH];
	buffer[0] = '\0';
	log_verbose("buffer = '%s'", buffer);
	const char *homedir = getenv("XDG_CONFIG_HOME");
	log_verbose("homedir = '%s'", homedir);
	if (homedir == NULL)
	{
		homedir = getpwuid(getuid())->pw_dir;
		log_verbose("homedir was null, used getuid, now is = '%s'", homedir);
		if (homedir == NULL)
		{
			log_fatal("Couldn't find user data directory");
			exit(-1);
			return;
		}

		strncat(buffer, homedir, MAX_PATH);
		strncat(buffer, separator, MAX_PATH);
		strncat(buffer, ".config", MAX_PATH);
	}
	else
	{
		strncat(buffer, homedir, MAX_PATH);
	}
	strncat(buffer, separator, MAX_PATH);
	strncat(buffer, "OpenRCT2", MAX_PATH);
	strncat(buffer, separator, MAX_PATH);
	log_verbose("OpenRCT2 user data directory = '%s'", buffer);
	int len = strnlen(buffer, MAX_PATH);
	wchar_t *w_buffer = regular_to_wchar(buffer);
	w_buffer[len] = '\0';
	utf8 *path = widechar_to_utf8(w_buffer);
	free(w_buffer);
	safe_strncpy(_userDataDirectoryPath, path, MAX_PATH);
	free(path);
}
Пример #3
0
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize)
{
    char buffer[MAX_PATH];
    safe_strcpy(buffer, _userDataDirectoryPath, sizeof(buffer));
    if (subDirectory != NULL && subDirectory[0] != 0) {
        log_verbose("adding subDirectory '%s'", subDirectory);
        safe_strcat_path(buffer, subDirectory, sizeof(buffer));
        path_end_with_separator(buffer, sizeof(buffer));
    }
    sint32 len = strnlen(buffer, MAX_PATH);
    wchar_t *w_buffer = regular_to_wchar(buffer);
    w_buffer[len] = '\0';
    utf8 *path = widechar_to_utf8(w_buffer);
    free(w_buffer);
    safe_strcpy(outPath, path, outSize);
    free(path);
    log_verbose("outPath + subDirectory = '%s'", buffer);
}
Пример #4
0
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
{
	const char separator[2] = { platform_get_path_separator(), 0 };
	char buffer[MAX_PATH];
	safe_strcpy(buffer, _userDataDirectoryPath, sizeof(buffer));
	if (subDirectory != NULL && subDirectory[0] != 0) {
		log_verbose("adding subDirectory '%s'", subDirectory);
		strncat(buffer, subDirectory, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
		strncat(buffer, separator, MAX_PATH - strnlen(buffer, MAX_PATH) - 1);
	}
	int len = strnlen(buffer, MAX_PATH);
	wchar_t *w_buffer = regular_to_wchar(buffer);
	w_buffer[len] = '\0';
	utf8 *path = widechar_to_utf8(w_buffer);
	free(w_buffer);
	safe_strcpy(outPath, path, MAX_PATH);
	free(path);
	log_verbose("outPath + subDirectory = '%s'", buffer);
}
Пример #5
0
/**
 * Default directory fallback is:
 *   - (command line argument)
 *   - <platform dependent>
 */
void platform_resolve_user_data_path()
{

    if (gCustomUserDataPath[0] != 0) {
        if (!platform_ensure_directory_exists(gCustomUserDataPath)) {
            log_error("Failed to create directory \"%s\", make sure you have permissions.", gCustomUserDataPath);
            return;
        }
        char *path;
        if ((path = realpath(gCustomUserDataPath, NULL)) == NULL) {
            log_error("Could not resolve path \"%s\"", gCustomUserDataPath);
            return;
        }

        safe_strcpy(_userDataDirectoryPath, path, MAX_PATH);
        free(path);

        // Ensure path ends with separator
        path_end_with_separator(_userDataDirectoryPath, MAX_PATH);
        log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
        if (!platform_directory_exists(_userDataDirectoryPath)) {
            log_error("Custom user data directory %s does not exist", _userDataDirectoryPath);
        }
        return;
    }

    char buffer[MAX_PATH];
    log_verbose("buffer = '%s'", buffer);

    const char *homedir = getpwuid(getuid())->pw_dir;
    platform_posix_sub_user_data_path(buffer, MAX_PATH, homedir);

    log_verbose("OpenRCT2 user data directory = '%s'", buffer);
    sint32 len = strnlen(buffer, MAX_PATH);
    wchar_t *w_buffer = regular_to_wchar(buffer);
    w_buffer[len] = '\0';
    utf8 *path = widechar_to_utf8(w_buffer);
    free(w_buffer);
    safe_strcpy(_userDataDirectoryPath, path, MAX_PATH);
    free(path);
    log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
}
Пример #6
0
static bool OnCrash(const wchar_t * dumpPath,
                    const wchar_t * miniDumpId,
                    void * context,
                    EXCEPTION_POINTERS * exinfo,
                    MDRawAssertionInfo * assertion,
                    bool succeeded)
{
    if (!succeeded)
    {
        constexpr const char * DumpFailedMessage = "Failed to create the dump. Please file an issue with OpenRCT2 on GitHub and provide latest save, and provide information about what you did before the crash occured.";
        printf("%s\n", DumpFailedMessage);
        if (!gOpenRCT2SilentBreakpad)
        {
            MessageBoxA(NULL, DumpFailedMessage, OPENRCT2_NAME, MB_OK | MB_ICONERROR);
        }
        return succeeded;
    }

    // Get filenames
    wchar_t dumpFilePath[MAX_PATH];
    wchar_t saveFilePath[MAX_PATH];
    swprintf_s(dumpFilePath, sizeof(dumpFilePath), L"%s%s.dmp", dumpPath, miniDumpId);
    swprintf_s(saveFilePath, sizeof(saveFilePath), L"%s%s.sv6", dumpPath, miniDumpId);

    // Try to rename the files
    wchar_t dumpFilePathNew[MAX_PATH];
    swprintf_s(dumpFilePathNew, sizeof(dumpFilePathNew), L"%s%s(%s_%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short, _wszArchitecture);
    if (_wrename(dumpFilePath, dumpFilePathNew) == 0)
    {
        std::wcscpy(dumpFilePath, dumpFilePathNew);
    }

    // Log information to output
    wprintf(L"Dump Path: %s\n", dumpPath);
    wprintf(L"Dump File Path: %s\n", dumpFilePath);
    wprintf(L"Dump Id: %s\n", miniDumpId);
    wprintf(L"Version: %s\n", WSZ(OPENRCT2_VERSION));
    wprintf(L"Commit: %s\n", _wszCommitSha1Short);

    utf8 * saveFilePathUTF8 = widechar_to_utf8(saveFilePath);
    SDL_RWops * rw = SDL_RWFromFile(saveFilePathUTF8, "wb+");
    free(saveFilePathUTF8);

    bool savedGameDumped = false;
    if (rw != NULL) {
        scenario_save(rw, 0x80000000);
        savedGameDumped = true;
        SDL_RWclose(rw);
    }

    if (gOpenRCT2SilentBreakpad)
    {
        return succeeded;
    }
    constexpr const wchar_t * MessageFormat = L"A crash has occurred and a dump was created at\n%s.\n\nPlease file an issue with OpenRCT2 on GitHub, and provide the dump and saved game there.\n\nVersion: %s\nCommit: %s";
    wchar_t message[MAX_PATH * 2];
    swprintf_s(message,
               MessageFormat,
               dumpFilePath,
               WSZ(OPENRCT2_VERSION),
               _wszCommitSha1Short);

    // Cannot use platform_show_messagebox here, it tries to set parent window already dead.
    MessageBoxW(NULL, message, WSZ(OPENRCT2_NAME), MB_OK | MB_ICONERROR);
    HRESULT coInitializeResult = CoInitialize(NULL);
    if (SUCCEEDED(coInitializeResult))
    {
        LPITEMIDLIST pidl = ILCreateFromPathW(dumpPath);
        LPITEMIDLIST files[2];
        uint32 numFiles = 0;

        files[numFiles++] = ILCreateFromPathW(dumpFilePath);
        if (savedGameDumped)
        {
            files[numFiles++] = ILCreateFromPathW(saveFilePath);
        }
        if (pidl != nullptr) {
            HRESULT result = SHOpenFolderAndSelectItems(pidl, numFiles, (LPCITEMIDLIST *)files, 0);
            ILFree(pidl);
            for (uint32 i = 0; i < numFiles; i++)
            {
                ILFree(files[i]);
            }
        }
        CoUninitialize();
    }

    // Return whether the dump was successful
    return succeeded;
}