// Handle for Zlib DLL
static dllhandle_t zlib_dll = NULL;
+#ifdef WIN32
+static HRESULT (WINAPI *qSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
+static dllfunction_t shfolderfuncs[] =
+{
+ {"SHGetFolderPathA", (void **) &qSHGetFolderPath},
+ {NULL, NULL}
+};
+static dllhandle_t shfolder_dll = NULL;
+#endif
/*
====================
// Check encryption, compression, and attributes
// 1st uint8 : general purpose bit flag
// Check bits 0 (encryption), 3 (data descriptor after the file), and 5 (compressed patched data (?))
+ //
+ // LordHavoc: bit 3 would be a problem if we were scanning the archive
+ // but is not a problem in the central directory where the values are
+ // always real.
+ //
+ // bit 3 seems to always be set by the standard Mac OSX zip maker
+ //
// 2nd uint8 : external file attributes
// Check bits 3 (file is a directory) and 5 (file is a volume (?))
- if ((ptr[8] & 0x29) == 0 && (ptr[38] & 0x18) == 0)
+ if ((ptr[8] & 0x21) == 0 && (ptr[38] & 0x18) == 0)
{
// Still enough bytes for the name?
if (remaining < namesize || namesize >= (int)sizeof (*pack->files))
char userdir[MAX_QPATH];
#ifdef WIN32
TCHAR mydocsdir[MAX_PATH + 1];
-#else
- const char *homedir;
#endif
+ const char *homedir;
// Add the common game directory
FS_AddGameDirectory (va("%s%s/", fs_basedir, dir));
// Add the personal game directory
#ifdef WIN32
- if(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK)
+ if(qSHGetFolderPath && (qSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK))
+ {
dpsnprintf(userdir, sizeof(userdir), "%s/My Games/%s/", mydocsdir, gameuserdirname);
- fprintf(stderr, "userdir = %s\n", userdir);
+ Con_DPrintf("Obtained personal directory %s from SHGetFolderPath\n", userdir);
+ }
+ else
+ {
+ // use the environment
+ homedir = getenv ("USERPROFILE");
+ if(homedir)
+ {
+ dpsnprintf(userdir, sizeof(userdir), "%s/My Documents/My Games/%s/", homedir, gameuserdirname);
+ Con_DPrintf("Obtained personal directory %s from environment\n", userdir);
+ }
+ else
+ *userdir = 0; // just to make sure it hasn't been written to by SHGetFolderPath returning failure
+ }
+
+ if(!*userdir)
+ Con_DPrintf("Could not obtain home directory; not supporting -mygames\n");
#else
homedir = getenv ("HOME");
if(homedir)
dpsnprintf(userdir, sizeof(userdir), "%s/.%s/", homedir, gameuserdirname);
+
+ if(!*userdir)
+ Con_DPrintf("Could not obtain home directory; assuming -nohome\n");
#endif
+
#ifdef WIN32
if(!COM_CheckParm("-mygames"))
{
if(COM_CheckParm("-nohome"))
*userdir = 0;
-
+
if((i = COM_CheckParm("-userdir")) && i < com_argc - 1)
dpsnprintf(userdir, sizeof(userdir), "%s/", com_argv[i+1]);
}
}
- // halt demo playback to close the file
- CL_Disconnect();
-
Host_SaveConfig();
fs_numgamedirs = numgamedirs;
return;
}
+ // halt demo playback to close the file
+ CL_Disconnect();
+
FS_ChangeGameDirs(numgamedirs, gamedirs, true, true);
}
{
int i;
+#ifdef WIN32
+ const char* dllnames [] =
+ {
+ "shfolder.dll", // IE 4, or Win NT and higher
+ NULL
+ };
+ Sys_LoadLibrary(dllnames, &shfolder_dll, shfolderfuncs);
+ // don't care for the result; if it fails, %USERPROFILE% will be used instead
+#endif
+
fs_mempool = Mem_AllocPool("file management", 0, NULL);
strlcpy(fs_gamedir, "", sizeof(fs_gamedir));
strlcat(fs_basedir, "/", sizeof(fs_basedir));
if (!FS_CheckGameDir(gamedirname1))
- Sys_Error("base gamedir %s%s/ not found!\n", fs_basedir, gamedirname1);
+ Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname1);
if (gamedirname2 && !FS_CheckGameDir(gamedirname2))
- Sys_Error("base gamedir %s%s/ not found!\n", fs_basedir, gamedirname2);
+ Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname2);
// -game <gamedir>
// Adds basedir/gamedir as an override game
if (FS_CheckNastyPath(com_argv[i], true))
Sys_Error("-game %s%s/ is a dangerous/non-portable path\n", fs_basedir, com_argv[i]);
if (!FS_CheckGameDir(com_argv[i]))
- Sys_Error("-game %s%s/ not found!\n", fs_basedir, com_argv[i]);
+ Con_Printf("WARNING: -game %s%s/ not found!\n", fs_basedir, com_argv[i]);
// add the gamedir to the list of active gamedirs
strlcpy (fs_gamedirs[fs_numgamedirs], com_argv[i], sizeof(fs_gamedirs[fs_numgamedirs]));
fs_numgamedirs++;
// by the OS anyway)
FS_ClearSearchPath();
Mem_FreePool (&fs_mempool);
+
+#ifdef WIN32
+ Sys_UnloadLibrary (&shfolder_dll);
+#endif
}
/*
*/
qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet, qboolean nonblocking)
{
-#ifdef FS_FIX_PATHS
- char fixedFileName[MAX_QPATH];
- char *d;
- strlcpy( fixedFileName, filepath, MAX_QPATH );
- // try to fix common mistakes (\ instead of /)
- for( d = fixedFileName ; *d ; d++ )
- if( *d == '\\' )
- *d = '/';
- filepath = fixedFileName;
-#endif
-
if (FS_CheckNastyPath(filepath, false))
{
Con_Printf("FS_Open(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false");
if( !nextseparator ) {
nextseparator = start + strlen( start );
}
-
+
// prevseparator points past the '/' right before the wildcard and nextseparator at the one following it (or at the end of the string)
// copy everything up except nextseperator
strlcpy(subpattern, pattern, min(sizeof(subpattern), (size_t) (nextseparator - pattern + 1)));
// find the last '/' before the wildcard
- prevseparator = strrchr( subpattern, '/' ) + 1;
+ prevseparator = strrchr( subpattern, '/' );
if (!prevseparator)
- {
prevseparator = subpattern;
- }
+ else
+ prevseparator++;
// copy everything from start to the previous including the '/' (before the wildcard)
// everything up to start is already included in the path of matchedSet's entries
strlcpy(subpath, start, min(sizeof(subpath), (size_t) ((prevseparator - subpattern) - (start - pattern) + 1)));
-
+
// for each entry in matchedSet try to open the subdirectories specified in subpath
for( dirlistindex = 0 ; dirlistindex < matchedSet.numstrings ; dirlistindex++ ) {
strlcpy( temp, matchedSet.strings[ dirlistindex ], sizeof(temp) );
strlcat( temp, subpath, sizeof(temp) );
- listdirectory( &foundSet, searchpath->filename, temp );
+ listdirectory( &foundSet, searchpath->filename, temp );
}
if( dirlistindex == 0 ) {
break;
start = nextseparator;
}
-
+
for (dirlistindex = 0;dirlistindex < matchedSet.numstrings;dirlistindex++)
{
const char *temp = matchedSet.strings[dirlistindex];