Index: zpath.c
===================================================================
--- zpath.c (revision 4803)
+++ zpath.c (working copy)
@@ -27,6 +27,7 @@
#ifdef __WIN32__
#include <io.h>
#include <direct.h>
+#include <shlobj.h> /* Needed for per user configuration support */
#include "win/safelib.h"
#include "win/lib.h"
#else
@@ -122,17 +123,60 @@
{
char *p = 0;
ZCfgAlloc = true;
-
- if (isextension(launch_command, "exe"))
+
+#ifdef __WIN32__
{
- p = realpath(launch_command, ZCfgPath);
+ /* This code change allows ZSNES to support per-user configuration on
+ Windows just as it does in Linux, etc.
+
+ On 9x system that are configured to use only a single user profile,
+ the configuration folder will be:
+
+ C:\Windows\Application Data\zsnes
+
+ On 9x systems that are configured to use a profile per user, it will be
+
+ C:\Windows\Profile\<username>Application Data\zsnes
+
+ On 2000/XP/later systems, it will be
+
+ C:\Documents and Settings\<username>\Application Data\zsnes
+
+ If it can not determine the directory, it will fall back to the
+ default of user the configuration file in the same directory as
+ the executable */
+
+ const char *const zpath = "zsnes";
+
+ /* No problem with buffer size, PATH_SIZE > MAX_PATH on Windows */
+ if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, ZCfgPath) == 0 /* S_OK */)
+ {
+ strcatslash(ZCfgPath);
+ strcat(ZCfgPath, zpath);
+ if (mkpath(ZCfgPath, 0755))
+ {
+ strcatslash(ZCfgPath);
+ strcat(ZCfgPath, ZCfgFile); /* Needed for strdirname below */
+ p = ZCfgPath;
+ }
+ }
}
- else
+#endif
+
+ /* Unable to do per-user configuration, fall back to program directory */
+ if (p == 0)
{
- char buff[PATH_SIZE];
- strcpy(buff, launch_command);
- setextension(buff, "exe");
- p = realpath(buff, ZCfgPath);
+ if (isextension(launch_command, "exe"))
+ {
+ p = realpath(launch_command, ZCfgPath);
+ }
+ else
+ {
+ char buff[PATH_SIZE];
+ strcpy(buff, launch_command);
+ setextension(buff, "exe");
+ p = realpath(buff, ZCfgPath);
+ }
}
if (p)
@@ -594,7 +638,21 @@
{
struct stat stat_buffer;
p = strchr(element, DIR_SLASH_C);
+
+#ifdef __WIN32__
+ /* stat code below fails on actual drive like 'C:', so skip past that part */
+ if (p)
+ {
+ if( *(p - 1) == ':')
+ {
+ p = strchr(p + 1, DIR_SLASH_C);
+ }
+
+ if (p) { *p = 0; }
+ }
+#else
if (p) { *p = 0; }
+#endif
//Current path fragment created or already exists as a directory already
if ((created = !mkdir_p(path)) || (!stat(path, &stat_buffer) && S_ISDIR(stat_buffer.st_mode)))