Index: zpath.c =================================================================== --- zpath.c (revision 4803) +++ zpath.c (working copy) @@ -27,6 +27,7 @@ #ifdef __WIN32__ #include #include +#include /* 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\Application Data\zsnes + + On 2000/XP/later systems, it will be + + C:\Documents and Settings\\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)))