[Scummvm-git-logs] scummvm master -> e82f6c6dcda64ee89b2680a827f13e617793a094

lotharsm mail at serra.me
Sat Nov 13 20:22:33 UTC 2021


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
3d6524c9f4 WIN32: Add Portable Mode
9dbbc8f7c4 NEWS: Mention Windows Portable Mode
88d66166fb NEWS: Fix whitespace
6842e6f5a9 WIN32: Disable update checks in Portable Mode
e82f6c6dcd GUI: Hide update controls when UpdateManager not set


Commit: 3d6524c9f43d6e2e9ed95b192cf61342b9aea2e6
    https://github.com/scummvm/scummvm/commit/3d6524c9f43d6e2e9ed95b192cf61342b9aea2e6
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-11-13T21:22:28+01:00

Commit Message:
WIN32: Add Portable Mode

Adds support for a self-contained portable mode in which the
executable's directory is used for application files instead
of directories in the user's profile.

Portable mode is activated by placing a scummvm.ini file in
the executable's directory. The directory must be outside of
the system's Program Files directory to comply with UAC.

Changed paths:
    backends/platform/sdl/win32/win32.cpp
    backends/platform/sdl/win32/win32.h
    backends/platform/sdl/win32/win32_wrapper.cpp
    backends/platform/sdl/win32/win32_wrapper.h
    backends/saves/windows/windows-saves.cpp
    backends/saves/windows/windows-saves.h


diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 14b97d8050..4024c3b95a 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -59,6 +59,10 @@
 
 #define DEFAULT_CONFIG_FILE "scummvm.ini"
 
+OSystem_Win32::OSystem_Win32() :
+	_isPortable(false) {
+}
+
 void OSystem_Win32::init() {
 	// Initialize File System Factory
 	_fsFactory = new WindowsFilesystemFactory();
@@ -112,8 +116,8 @@ void OSystem_Win32::initBackend() {
 	}
 
 	// Create the savefile manager
-	if (_savefileManager == 0)
-		_savefileManager = new WindowsSaveFileManager();
+	if (_savefileManager == nullptr)
+		_savefileManager = new WindowsSaveFileManager(_isPortable);
 
 #if defined(USE_SPARKLE)
 	// Initialize updates manager
@@ -240,16 +244,19 @@ Common::String OSystem_Win32::getScreenshotsPath() {
 		return screenshotsPath;
 	}
 
-	// Use the My Pictures folder.
 	TCHAR picturesPath[MAX_PATH];
-
-	if (SHGetFolderPathFunc(NULL, CSIDL_MYPICTURES, NULL, SHGFP_TYPE_CURRENT, picturesPath) != S_OK) {
-		warning("Unable to access My Pictures directory");
-		return Common::String();
+	if (_isPortable) {
+		Win32::getProcessDirectory(picturesPath, MAX_PATH);
+		_tcscat(picturesPath, TEXT("\\Screenshots\\"));
+	} else {
+		// Use the My Pictures folder
+		if (SHGetFolderPathFunc(NULL, CSIDL_MYPICTURES, NULL, SHGFP_TYPE_CURRENT, picturesPath) != S_OK) {
+			warning("Unable to access My Pictures directory");
+			return Common::String();
+		}
+		_tcscat(picturesPath, TEXT("\\ScummVM Screenshots\\"));
 	}
 
-	_tcscat(picturesPath, TEXT("\\ScummVM Screenshots\\"));
-
 	// If the directory already exists (as it should in most cases),
 	// we don't want to fail, but we need to stop on other errors (such as ERROR_PATH_NOT_FOUND)
 	if (!CreateDirectory(picturesPath, NULL)) {
@@ -263,41 +270,48 @@ Common::String OSystem_Win32::getScreenshotsPath() {
 Common::String OSystem_Win32::getDefaultConfigFileName() {
 	TCHAR configFile[MAX_PATH];
 
-	// Use the Application Data directory of the user profile.
-	if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, configFile) == S_OK) {
-		_tcscat(configFile, TEXT("\\ScummVM"));
-		if (!CreateDirectory(configFile, NULL)) {
-			if (GetLastError() != ERROR_ALREADY_EXISTS)
-				error("Cannot create ScummVM application data folder");
-		}
+	// if this is the first time the default config file name is requested
+	// then we need detect if we should run in portable mode. (and if it's
+	// never requested before the backend is initialized then a config file
+	// was provided on the command line and portable mode doesn't apply.)
+	if (!backendInitialized()) {
+		_isPortable = detectPortableConfigFile();
+	}
 
+	if (_isPortable) {
+		// Use the current process directory in portable mode
+		Win32::getProcessDirectory(configFile, MAX_PATH);
 		_tcscat(configFile, TEXT("\\" DEFAULT_CONFIG_FILE));
-
-		FILE *tmp = NULL;
-		if ((tmp = _tfopen(configFile, TEXT("r"))) == NULL) {
+	} else {
+		// Use the Application Data directory of the user profile
+		if (Win32::getApplicationDataDirectory(configFile)) {
+			_tcscat(configFile, TEXT("\\" DEFAULT_CONFIG_FILE));
+
+			FILE *tmp = NULL;
+			if ((tmp = _tfopen(configFile, TEXT("r"))) == NULL) {
+				// Check windows directory
+				TCHAR oldConfigFile[MAX_PATH];
+				uint ret = GetWindowsDirectory(oldConfigFile, MAX_PATH);
+				if (ret == 0 || ret > MAX_PATH)
+					error("Cannot retrieve the path of the Windows directory");
+
+				_tcscat(oldConfigFile, TEXT("\\" DEFAULT_CONFIG_FILE));
+				if ((tmp = _tfopen(oldConfigFile, TEXT("r")))) {
+					_tcscpy(configFile, oldConfigFile);
+
+					fclose(tmp);
+				}
+			} else {
+				fclose(tmp);
+			}
+		} else {
 			// Check windows directory
-			TCHAR oldConfigFile[MAX_PATH];
-			uint ret = GetWindowsDirectory(oldConfigFile, MAX_PATH);
+			uint ret = GetWindowsDirectory(configFile, MAX_PATH);
 			if (ret == 0 || ret > MAX_PATH)
 				error("Cannot retrieve the path of the Windows directory");
 
-			_tcscat(oldConfigFile, TEXT("\\" DEFAULT_CONFIG_FILE));
-			if ((tmp = _tfopen(oldConfigFile, TEXT("r")))) {
-				_tcscpy(configFile, oldConfigFile);
-
-				fclose(tmp);
-			}
-		} else {
-			fclose(tmp);
+			_tcscat(configFile, TEXT("\\" DEFAULT_CONFIG_FILE));
 		}
-	} else {
-		warning("Unable to access application data directory");
-		// Check windows directory
-		uint ret = GetWindowsDirectory(configFile, MAX_PATH);
-		if (ret == 0 || ret > MAX_PATH)
-			error("Cannot retrieve the path of the Windows directory");
-
-		_tcscat(configFile, TEXT("\\" DEFAULT_CONFIG_FILE));
 	}
 
 	return Win32::tcharToString(configFile);
@@ -306,21 +320,54 @@ Common::String OSystem_Win32::getDefaultConfigFileName() {
 Common::String OSystem_Win32::getDefaultLogFileName() {
 	TCHAR logFile[MAX_PATH];
 
-	// Use the Application Data directory of the user profile.
-	if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, logFile) != S_OK) {
-		warning("Unable to access application data directory");
-		return Common::String();
+	if (_isPortable) {
+		Win32::getProcessDirectory(logFile, MAX_PATH);
+	} else {
+		// Use the Application Data directory of the user profile
+		if (!Win32::getApplicationDataDirectory(logFile)) {
+			return Common::String();
+		}
+		_tcscat(logFile, TEXT("\\Logs"));
+		CreateDirectory(logFile, NULL);
 	}
 
-	_tcscat(logFile, TEXT("\\ScummVM"));
-	CreateDirectory(logFile, NULL);
-	_tcscat(logFile, TEXT("\\Logs"));
-	CreateDirectory(logFile, NULL);
 	_tcscat(logFile, TEXT("\\scummvm.log"));
 
 	return Win32::tcharToString(logFile);
 }
 
+bool OSystem_Win32::detectPortableConfigFile() {
+	// ScummVM operates in a "portable mode" if there is a config file in the
+	// same directory as the executable. In this mode, the executable's
+	// directory is used instead of the user's profile for application files.
+	// This approach is modeled off of the portable mode in Notepad++.
+
+	// Check if there is a config file in the same directory as the executable.
+	TCHAR portableConfigFile[MAX_PATH];
+	Win32::getProcessDirectory(portableConfigFile, MAX_PATH);
+	_tcscat(portableConfigFile, TEXT("\\" DEFAULT_CONFIG_FILE));
+	FILE *file = _tfopen(portableConfigFile, TEXT("r"));
+	if (file == NULL) {
+		return false;
+	}
+	fclose(file);
+
+	// Check if we're running from Program Files on Vista+.
+	// If so then don't attempt to use local files due to UAC.
+	// (Notepad++ does this too.)
+	if (Win32::confirmWindowsVersion(6, 0)) {
+		TCHAR programFiles[MAX_PATH];
+		if (SHGetFolderPathFunc(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, programFiles) == S_OK) {
+			_tcscat(portableConfigFile, TEXT("\\"));
+			if (_tcsstr(portableConfigFile, programFiles) == portableConfigFile) {
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
 namespace {
 
 class Win32ResourceArchive final : public Common::Archive {
diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h
index 126267c385..c26d285da7 100644
--- a/backends/platform/sdl/win32/win32.h
+++ b/backends/platform/sdl/win32/win32.h
@@ -28,6 +28,8 @@
 
 class OSystem_Win32 final : public OSystem_SDL {
 public:
+	OSystem_Win32();
+
 	virtual void init() override;
 	virtual void initBackend() override;
 
@@ -58,6 +60,10 @@ protected:
 	virtual AudioCDManager *createAudioCDManager() override;
 
 	HWND getHwnd() { return ((SdlWindow_Win32*)_window)->getHwnd(); }
+
+private:
+	bool _isPortable;
+	bool detectPortableConfigFile();
 };
 
 #endif
diff --git a/backends/platform/sdl/win32/win32_wrapper.cpp b/backends/platform/sdl/win32/win32_wrapper.cpp
index 00ce8fe75c..e38efe1096 100644
--- a/backends/platform/sdl/win32/win32_wrapper.cpp
+++ b/backends/platform/sdl/win32/win32_wrapper.cpp
@@ -28,8 +28,10 @@
 #define _WIN32_IE 0x400
 #endif
 #include <shlobj.h>
+#include <tchar.h>
 
 #include "common/scummsys.h"
+#include "common/textconsole.h"
 #include "backends/platform/sdl/win32/win32_wrapper.h"
 
 // VerSetConditionMask, VerifyVersionInfo and SHGetFolderPath didn't appear until Windows 2000,
@@ -72,6 +74,33 @@ HRESULT SHGetFolderPathFunc(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
 
 namespace Win32 {
 
+bool getApplicationDataDirectory(TCHAR *applicationDataDirectory) {
+	if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, applicationDataDirectory) != S_OK) {
+		warning("Unable to access application data directory");
+		return false;
+	}
+
+	_tcscat(applicationDataDirectory, TEXT("\\ScummVM"));
+	if (!CreateDirectory(applicationDataDirectory, NULL)) {
+		if (GetLastError() != ERROR_ALREADY_EXISTS) {
+			error("Cannot create ScummVM application data folder");
+		}
+	}
+
+	return true;
+}
+
+void getProcessDirectory(TCHAR *processDirectory, DWORD size) {
+	GetModuleFileName(NULL, processDirectory, size);
+	processDirectory[size - 1] = '\0'; // termination not guaranteed
+
+	// remove executable and final path separator
+	TCHAR *lastSeparator = _tcsrchr(processDirectory, '\\');
+	if (lastSeparator != NULL) {
+		*lastSeparator = '\0';
+	}
+}
+
 bool confirmWindowsVersion(int majorVersion, int minorVersion) {
 	OSVERSIONINFOEXA versionInfo;
 	DWORDLONG conditionMask = 0;
@@ -173,4 +202,4 @@ void freeArgvUtf8(int argc, char **argv) {
 }
 #endif
 
-}
+} // End of namespace Win32
diff --git a/backends/platform/sdl/win32/win32_wrapper.h b/backends/platform/sdl/win32/win32_wrapper.h
index 8b6411b155..97a57b73f8 100644
--- a/backends/platform/sdl/win32/win32_wrapper.h
+++ b/backends/platform/sdl/win32/win32_wrapper.h
@@ -31,6 +31,29 @@ HRESULT SHGetFolderPathFunc(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags,
 // Helper functions
 namespace Win32 {
 
+/**
+ * Gets the full path to the ScummVM application data directory
+ * in the user's profile and creates it if it doesn't exist.
+ *
+ * @param profileDirectory MAX_PATH sized output array
+ *
+ * @return True if the user's profile directory was found, false if
+ * it was not.
+ *
+ * @note if the user's profile directory is found but the "ScummVM"
+ * subdirectory can't be created then this function calls error().
+ */
+bool getApplicationDataDirectory(TCHAR *profileDirectory);
+
+/**
+ * Gets the full path to the directory that the currently executing
+ * process resides in.
+ *
+ * @param processDirectory output array
+ * @param size size in characters of output array
+ */
+void getProcessDirectory(TCHAR *processDirectory, DWORD size);
+
 /**
  * Checks if the current running Windows version is greater or equal to the specified version.
  * See: https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
@@ -115,6 +138,6 @@ char **getArgvUtf8(int *argc);
 void freeArgvUtf8(int argc, char **argv);
 #endif
 
-}
+} // End of namespace Win32
 
 #endif
diff --git a/backends/saves/windows/windows-saves.cpp b/backends/saves/windows/windows-saves.cpp
index 4488f1db6f..53aa12efc8 100644
--- a/backends/saves/windows/windows-saves.cpp
+++ b/backends/saves/windows/windows-saves.cpp
@@ -36,27 +36,25 @@
 #include "backends/saves/windows/windows-saves.h"
 #include "backends/platform/sdl/win32/win32_wrapper.h"
 
-WindowsSaveFileManager::WindowsSaveFileManager() {
+WindowsSaveFileManager::WindowsSaveFileManager(bool isPortable) {
 	TCHAR defaultSavepath[MAX_PATH];
 
-	// Use the Application Data directory of the user profile.
-	if (SHGetFolderPathFunc(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, defaultSavepath) == S_OK) {
-		_tcscat(defaultSavepath, TEXT("\\ScummVM"));
-		if (!CreateDirectory(defaultSavepath, NULL)) {
-			if (GetLastError() != ERROR_ALREADY_EXISTS)
-				error("Cannot create ScummVM application data folder");
-		}
-
-		_tcscat(defaultSavepath, TEXT("\\Saved games"));
-		if (!CreateDirectory(defaultSavepath, NULL)) {
-			if (GetLastError() != ERROR_ALREADY_EXISTS)
-				error("Cannot create ScummVM Saved games folder");
+	if (isPortable) {
+		Win32::getProcessDirectory(defaultSavepath, MAX_PATH);
+	} else {
+		// Use the Application Data directory of the user profile
+		if (!Win32::getApplicationDataDirectory(defaultSavepath)) {
+			return;
 		}
+	}
 
-		ConfMan.registerDefault("savepath", Win32::tcharToString(defaultSavepath));
-	} else {
-		warning("Unable to access application data directory");
+	_tcscat(defaultSavepath, TEXT("\\Saved games"));
+	if (!CreateDirectory(defaultSavepath, NULL)) {
+		if (GetLastError() != ERROR_ALREADY_EXISTS)
+			error("Cannot create ScummVM Saved games folder");
 	}
+
+	ConfMan.registerDefault("savepath", Win32::tcharToString(defaultSavepath));
 }
 
 #endif
diff --git a/backends/saves/windows/windows-saves.h b/backends/saves/windows/windows-saves.h
index 66b5b034a8..8b8315d9ba 100644
--- a/backends/saves/windows/windows-saves.h
+++ b/backends/saves/windows/windows-saves.h
@@ -26,11 +26,11 @@
 #include "backends/saves/default/default-saves.h"
 
 /**
- * Provides a default savefile manager implementation for common platforms.
+ * Provides a savefile manager implementation for Windows.
  */
 class WindowsSaveFileManager final : public DefaultSaveFileManager {
 public:
-	WindowsSaveFileManager();
+	WindowsSaveFileManager(bool isPortable);
 };
 
 #endif


Commit: 9dbbc8f7c42c7a229a03114a3465c8dfe987a0f5
    https://github.com/scummvm/scummvm/commit/9dbbc8f7c42c7a229a03114a3465c8dfe987a0f5
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-11-13T21:22:28+01:00

Commit Message:
NEWS: Mention Windows Portable Mode

Changed paths:
    NEWS.md


diff --git a/NEWS.md b/NEWS.md
index ae720027f1..1620417d8f 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -32,6 +32,11 @@ For a more comprehensive changelog of the latest experimental code, see:
    - Fix crash on startup loading constants from xeen.ccs.
    - Fix spell selection aborting when characters were switched.
    - Fixed some bad memory accesses.
+   
+ Windows port:
+   - Added "Portable Mode" in which the executable's directory is used to store
+     application files if a scummvm.ini file is present, instead of the user's
+	 profile directory.
 
 #### 2.5.0 "Twenty years ago today..." (2021-10-09)
 


Commit: 88d66166fb5fe5b64128e9e46cd510c5e74baad3
    https://github.com/scummvm/scummvm/commit/88d66166fb5fe5b64128e9e46cd510c5e74baad3
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2021-11-13T21:22:28+01:00

Commit Message:
NEWS: Fix whitespace

Changed paths:
    NEWS.md


diff --git a/NEWS.md b/NEWS.md
index 1620417d8f..52957fbb2f 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -36,7 +36,7 @@ For a more comprehensive changelog of the latest experimental code, see:
  Windows port:
    - Added "Portable Mode" in which the executable's directory is used to store
      application files if a scummvm.ini file is present, instead of the user's
-	 profile directory.
+     profile directory.
 
 #### 2.5.0 "Twenty years ago today..." (2021-10-09)
 


Commit: 6842e6f5a9249af77c1ee295ef4b8f7a0fe26b7c
    https://github.com/scummvm/scummvm/commit/6842e6f5a9249af77c1ee295ef4b8f7a0fe26b7c
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-11-13T21:22:28+01:00

Commit Message:
WIN32: Disable update checks in Portable Mode

Changed paths:
    backends/platform/sdl/win32/win32.cpp


diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
index 4024c3b95a..4fdacb8019 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -121,7 +121,9 @@ void OSystem_Win32::initBackend() {
 
 #if defined(USE_SPARKLE)
 	// Initialize updates manager
-	_updateManager = new Win32UpdateManager((SdlWindow_Win32*)_window);
+	if (!_isPortable) {
+		_updateManager = new Win32UpdateManager((SdlWindow_Win32*)_window);
+	}
 #endif
 
 	// Initialize text to speech


Commit: e82f6c6dcda64ee89b2680a827f13e617793a094
    https://github.com/scummvm/scummvm/commit/e82f6c6dcda64ee89b2680a827f13e617793a094
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-11-13T21:22:28+01:00

Commit Message:
GUI: Hide update controls when UpdateManager not set

Changed paths:
    gui/options.cpp


diff --git a/gui/options.cpp b/gui/options.cpp
index ea6ed32c83..5d89ab1fd2 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -2399,18 +2399,20 @@ void GlobalOptionsDialog::addMiscControls(GuiObject *boss, const Common::String
 	}
 
 #ifdef USE_UPDATES
-	_updatesPopUpDesc = new StaticTextWidget(boss, prefix + "UpdatesPopupDesc", _("Update check:"), _("How often to check ScummVM updates"));
-	_updatesPopUp = new PopUpWidget(boss, prefix + "UpdatesPopup");
+	if (g_system->getUpdateManager()) {
+		_updatesPopUpDesc = new StaticTextWidget(boss, prefix + "UpdatesPopupDesc", _("Update check:"), _("How often to check ScummVM updates"));
+		_updatesPopUp = new PopUpWidget(boss, prefix + "UpdatesPopup");
 
-	const int *vals = Common::UpdateManager::getUpdateIntervals();
-	while (*vals != -1) {
-		_updatesPopUp->appendEntry(Common::UpdateManager::updateIntervalToString(*vals), *vals);
-		vals++;
-	}
+		const int *vals = Common::UpdateManager::getUpdateIntervals();
+		while (*vals != -1) {
+			_updatesPopUp->appendEntry(Common::UpdateManager::updateIntervalToString(*vals), *vals);
+			vals++;
+		}
 
-	_updatesPopUp->setSelectedTag(Common::UpdateManager::normalizeInterval(ConfMan.getInt("updates_check")));
+		_updatesPopUp->setSelectedTag(Common::UpdateManager::normalizeInterval(ConfMan.getInt("updates_check")));
 
-	new ButtonWidget(boss, prefix + "UpdatesCheckManuallyButton", _("Check now"), Common::U32String(), kUpdatesCheckCmd);
+		new ButtonWidget(boss, prefix + "UpdatesCheckManuallyButton", _("Check now"), Common::U32String(), kUpdatesCheckCmd);
+	}
 #endif // USE_UPDATES
 }
 
@@ -2687,9 +2689,9 @@ void GlobalOptionsDialog::apply() {
 		_autosavePeriodPopUp->setSelected(0);
 
 #ifdef USE_UPDATES
-	ConfMan.setInt("updates_check", _updatesPopUp->getSelectedTag());
-
 	if (g_system->getUpdateManager()) {
+		ConfMan.setInt("updates_check", _updatesPopUp->getSelectedTag());
+		
 		if (_updatesPopUp->getSelectedTag() == Common::UpdateManager::kUpdateIntervalNotSupported) {
 			g_system->getUpdateManager()->setAutomaticallyChecksForUpdates(Common::UpdateManager::kUpdateStateDisabled);
 		} else {




More information about the Scummvm-git-logs mailing list