No longer use SHGetFolderPath on MS Windows.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@525 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
meep-eep
2003-01-03 00:51:10 +00:00
parent 67212a7491
commit c4ae25cccd
+65 -74
View File
@@ -28,23 +28,14 @@
#ifdef WIN32 #ifdef WIN32
# include <direct.h> # include <direct.h>
// this would lead to conflicts
//# include <shlobj.h>
typedef void *HWND;
typedef void *HANDLE;
typedef char *LPTSTR;
typedef long HRESULT;
#define SUCCEEDED(Status) ((HRESULT) (Status) >= 0)
HRESULT __stdcall SHGetFolderPathA (HWND hwndOwner, int nFolder,
HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
#define SHGetFolderPath SHGetFolderPathA
#define CSIDL_APPDATA 0x001a // <user name>\Application Data
#define CSIDL_FLAG_CREATE 0x8000
// combine with CSIDL_ value to force folder creation in
// SHGetFolderPath()
#endif #endif
/* Try to find a suitable value for %APPDATA% if it isn't defined on
* Windows.
*/
#define APPDATA_FALLBACK
int int
createDirectory(const char *dir, int mode) createDirectory(const char *dir, int mode)
{ {
@@ -167,10 +158,11 @@ getHomeDir (void)
int int
expandPath (char *dest, size_t len, const char *src) expandPath (char *dest, size_t len, const char *src)
{ {
const char *destend; char *destend;
char *destptr;
#define CHECKLEN(n) \ #define CHECKLEN(n) \
if (dest + (n) > destend) \ if (destptr + (n) >= destend) \
{ \ { \
errno = ENAMETOOLONG; \ errno = ENAMETOOLONG; \
return -1; \ return -1; \
@@ -178,6 +170,7 @@ expandPath (char *dest, size_t len, const char *src)
else \ else \
(void) 0 (void) 0
destptr = dest;
destend = dest + len; destend = dest + len;
if (src[0] == '~') if (src[0] == '~')
{ {
@@ -199,8 +192,8 @@ expandPath (char *dest, size_t len, const char *src)
homelen = strlen (home); homelen = strlen (home);
CHECKLEN (homelen); CHECKLEN (homelen);
memcpy (dest, home, homelen); memcpy (destptr, home, homelen);
dest += homelen; destptr += homelen;
src++; /* skip the ~ */ src++; /* skip the ~ */
} }
@@ -208,14 +201,6 @@ expandPath (char *dest, size_t len, const char *src)
{ {
switch (*src) switch (*src)
{ {
#ifdef WIN32
case '\\':
/* Replaces backslashes in path by slashes in Windows. */
CHECKLEN(1);
*(dest++) = '/';
src++;
break;
#endif
#ifdef WIN32 #ifdef WIN32
case '%': case '%':
{ {
@@ -242,26 +227,56 @@ expandPath (char *dest, size_t len, const char *src)
if (envVar == NULL) if (envVar == NULL)
{ {
#if 1 #ifdef APPDATA_FALLBACK
if (strncmp (src, "APPDATA", envNameLen) == 0) if (strncmp (src, "APPDATA", envNameLen) != 0)
{ {
// fallback for when the APPDATA env var is not set // Substitute an empty string
if (getUserDataDir (dest, destend - dest) == -1)
return -1;
dest += strlen (dest);
src = end + 1; src = end + 1;
break; break;
} }
#endif
// fallback for when the APPDATA env var is not set
// Using SHGetFolderPath or SHGetSpecialFolderPath
// is problematic (not everywhere available).
fprintf(stderr, "Warning: %%APPDATA%% is not set. "
"Falling back to \"%%USERPROFILE%%\\Application "
"Data\"\n");
envVar = getenv ("USERPROFILE");
if (envVar != NULL)
{
#define APPDATA_STRING "\\Application Data"
envVarLen = strlen (envVar);
CHECKLEN (envVarLen + sizeof (APPDATA_STRING) - 1);
strcpy (destptr, envVar);
destptr += envVarLen;
strcpy (destptr, APPDATA_STRING);
destptr += sizeof (APPDATA_STRING) - 1;
src = end + 1;
break;
}
// fallback to "../userdata"
fprintf(stderr, "Warning: %%USERPROFILE%% is not set. "
"Falling back to \"..\\userdata\" for %%APPDATA%%"
"\n");
#define APPDATA_FALLBACK_STRING "..\\userdata"
CHECKLEN (sizeof (APPDATA_FALLBACK_STRING) - 1);
strcpy (destptr, APPDATA_FALLBACK_STRING);
destptr += sizeof (APPDATA_FALLBACK_STRING) - 1;
src = end + 1;
break;
#else /* !defined (APPDATA_FALLBACK) */
// Substitute an empty string // Substitute an empty string
src = end + 1; src = end + 1;
break; break;
#endif /* APPDATA_FALLBACK */
} }
envVarLen = strlen (envVar); envVarLen = strlen (envVar);
CHECKLEN (envVarLen); CHECKLEN (envVarLen);
strcpy (dest, envVar); strcpy (destptr, envVar);
dest += envVarLen; destptr += envVarLen;
src = end + 1; src = end + 1;
break; break;
} }
@@ -270,55 +285,31 @@ expandPath (char *dest, size_t len, const char *src)
case '$': case '$':
/* Environment variable substitution for Unix */ /* Environment variable substitution for Unix */
// not implemented // not implemented
// Should accept both $BLA_123 and ${BLA}
break; break;
#endif #endif
default: default:
CHECKLEN(1); CHECKLEN(1);
*(dest++) = *(src++); *(destptr++) = *(src++);
break; break;
} }
} }
*dest = '\0'; *destptr = '\0';
return 0;
}
// returns 0 on success, and fills dir with the path to the dir where there
// user data is stored.
// return -1 on error, and sets errno.
int
getUserDataDir (char *dir, size_t len)
{
#ifdef WIN32 #ifdef WIN32
char buf[PATH_MAX]; /* Replacing backslashes in path by slashes in Windows. */
destptr = dest;
if (!SUCCEEDED (SHGetFolderPath(NULL, while (*destptr != '\0')
CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buf)))
{ {
errno = ENOENT; if (*destptr == '\\')
return -1; {
*destptr = '/';
break;
}
destptr++;
} }
#endif
if (strlen (buf) >= len)
{
errno = ENAMETOOLONG;
return -1;
}
strcpy (dir, buf);
return 0; return 0;
#else
const char *homeDir;
homeDir = getHomeDir();
if (strlen (homeDir) >= len)
{
errno = ENAMETOOLONG;
return -1;
}
strcpy (dir, homeDir);
return 0;
#endif
} }
BOOLEAN BOOLEAN