r871 - trunk/platform
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Mar 25 02:26:53 EDT 2007
Author: icculus
Date: 2007-03-25 02:26:53 -0400 (Sun, 25 Mar 2007)
New Revision: 871
Modified:
trunk/platform/windows.c
Log:
Reworked getExePath() to remove some FIXMEs and respect Unicode.
Modified: trunk/platform/windows.c
===================================================================
--- trunk/platform/windows.c 2007-03-25 05:17:08 UTC (rev 870)
+++ trunk/platform/windows.c 2007-03-25 06:26:53 UTC (rev 871)
@@ -172,72 +172,73 @@
} /* win32strerror */
-static char *getExePath(const char *argv0)
+static char *getExePath(void)
{
- DWORD buflen;
+ DWORD buflen = 64;
int success = 0;
- char *ptr = NULL;
- char *retval = (char *) allocator.Malloc(sizeof (TCHAR) * (MAX_PATH + 1));
+ LPWSTR modpath = NULL;
+ char *retval = NULL;
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- retval[0] = '\0';
- /* !!! FIXME: don't preallocate here? */
- /* !!! FIXME: use smallAlloc? */
- /* !!! FIXME: unicode version. */
- buflen = GetModuleFileName(NULL, retval, MAX_PATH + 1);
- if (buflen <= 0)
- __PHYSFS_setError(win32strerror());
- else
+ while (1)
{
- retval[buflen] = '\0'; /* does API always null-terminate this? */
+ DWORD rc;
+ void *ptr;
- /* make sure the string was not truncated. */
- if (__PHYSFS_stricmpASCII(&retval[buflen - 4], ".exe") != 0)
- __PHYSFS_setError(ERR_GETMODFN_TRUNC);
- else
+ if ( !(ptr = allocator.Realloc(modpath, buflen*sizeof(WCHAR))) )
{
- ptr = strrchr(retval, '\\');
- if (ptr == NULL)
- __PHYSFS_setError(ERR_GETMODFN_NO_DIR);
- else
- {
- *(ptr + 1) = '\0'; /* chop off filename. */
- success = 1;
- } /* else */
- } /* else */
- } /* else */
+ allocator.Free(modpath);
+ BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+ modpath = (LPWSTR) ptr;
- /* if any part of the previous approach failed, try SearchPath()... */
+ rc = pGetModuleFileNameW(NULL, modpath, buflen);
+ if (rc == 0)
+ {
+ allocator.Free(modpath);
+ BAIL_MACRO(win32strerror(), NULL);
+ } /* if */
- if (!success)
+ if (rc < buflen)
+ {
+ buflen = rc;
+ break;
+ } /* if */
+
+ buflen *= 2;
+ } /* while */
+
+ if (buflen > 0) /* just in case... */
{
- if (argv0 == NULL) /* !!! FIXME: default behaviour does this. */
- __PHYSFS_setError(ERR_ARGV0_IS_NULL);
+ WCHAR *ptr = (modpath + buflen) - 1;
+ while (ptr != modpath)
+ {
+ if (*ptr == '\\')
+ break;
+ ptr--;
+ } /* while */
+
+ if ((ptr == modpath) && (*ptr != '\\'))
+ __PHYSFS_setError(ERR_GETMODFN_NO_DIR);
else
{
- /* !!! FIXME: unicode version. */
- buflen = SearchPath(NULL, argv0, NULL, MAX_PATH+1, retval, &ptr);
- if (buflen == 0)
- __PHYSFS_setError(win32strerror());
- else if (buflen > MAX_PATH)
- __PHYSFS_setError(ERR_SEARCHPATH_TRUNC);
+ *(ptr + 1) = '\0'; /* chop off filename. */
+ retval = (char *) allocator.Malloc(buflen * 6);
+ if (retval == NULL)
+ __PHYSFS_setError(ERR_OUT_OF_MEMORY);
else
- success = 1;
+ PHYSFS_utf8FromUcs2((const PHYSFS_uint16 *) modpath, retval, buflen * 6);
} /* else */
- } /* if */
+ } /* else */
+ allocator.Free(modpath);
- if (!success)
+ /* free up the bytes we didn't actually use. */
+ if (retval != NULL)
{
- allocator.Free(retval);
- return(NULL); /* physfs error message will be set, above. */
+ void *ptr = allocator.Realloc(retval, strlen(retval) + 1);
+ if (ptr != NULL)
+ retval = (char *) ptr;
} /* if */
- /* free up the bytes we didn't actually use. */
- ptr = (char *) allocator.Realloc(retval, strlen(retval) + 1);
- if (ptr != NULL)
- retval = ptr;
-
return(retval); /* w00t. */
} /* getExePath */
@@ -305,7 +306,7 @@
if (userDir == NULL) /* couldn't get profile for some reason. */
{
/* Might just be a non-NT system; resort to the basedir. */
- userDir = getExePath(NULL);
+ userDir = getExePath();
BAIL_IF_MACRO(userDir == NULL, NULL, 0); /* STILL failed?! */
} /* if */
@@ -352,7 +353,7 @@
if ((argv0 != NULL) && (strchr(argv0, '\\') != NULL))
return(NULL); /* default behaviour can handle this. */
- return(getExePath(argv0));
+ return(getExePath());
} /* __PHYSFS_platformCalcBaseDir */
More information about the physfs-commits
mailing list