From 3b798738f64a041751101d44504a239e6ebe4300 Mon Sep 17 00:00:00 2001 From: "Gregory S. Read" <18175637+readgs@users.noreply.github.com> Date: Sun, 24 Mar 2002 19:42:21 +0000 Subject: [PATCH] -Added init and deinit routines per physfs_internal.h changes. -User directory is now returned correctly under WinNT based systems. Under Win9x/ME, a NULL is returned right now. --- platform/win32.c | 161 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 138 insertions(+), 23 deletions(-) diff --git a/platform/win32.c b/platform/win32.c index 125b7645..012ac4cc 100644 --- a/platform/win32.c +++ b/platform/win32.c @@ -11,6 +11,7 @@ #endif #include +#include #include #include #include @@ -18,9 +19,16 @@ #define __PHYSICSFS_INTERNAL__ #include "physfs_internal.h" - const char *__PHYSFS_platformDirSeparator = "\\"; +static HANDLE ProcessHandle = NULL; /* Current process handle */ +static HANDLE AccessTokenHandle = NULL; /* Security handle to process */ +static DWORD ProcessID; /* ID assigned to current process */ +static int runningNT; /* TRUE if NT derived OS */ +static OSVERSIONINFO OSVersionInfo; /* Information about the OS */ + +/* NT specific information */ +static char *ProfileDirectory = NULL; /* User profile folder */ static const char *win32strerror(void) { @@ -72,7 +80,7 @@ char **__PHYSFS_platformDetectAvailableCDs(void) static char *getExePath(const char *argv0) { - char *filepart = NULL; + char *filepart = NULL; char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1)); DWORD buflen = GetModuleFileName(NULL, retval, MAX_PATH + 1); retval[buflen] = '\0'; /* does API always null-terminate the string? */ @@ -149,30 +157,15 @@ static char *copyEnvironmentVariable(const char *varname) char *__PHYSFS_platformGetUserDir(void) { - char *home = copyEnvironmentVariable("HOME"); - const char *homedrive = getenv("HOMEDRIVE"); - const char *homepath = getenv("HOMEPATH"); + char *userdir = NULL; - if (home != NULL) - return(home); - - if ((homedrive != NULL) && (homepath != NULL)) + /*!!!TODO - Need to get the userdir for non-NT based OSes */ + if(runningNT) { - char *retval = (char *) malloc(strlen(homedrive)+strlen(homepath)+2); - if (retval != NULL) - { - strcpy(retval, homedrive); - if ((homepath[0] != '\\') && - (homedrive[strlen(homedrive)-1] != '\\')) - { - strcat(retval, "\\"); - } /* if */ - strcat(retval, homepath); - return(retval); - } /* if */ - } /* if */ + userdir = ProfileDirectory; + } - return(NULL); + return userdir; } /* __PHYSFS_platformGetUserDir */ @@ -462,5 +455,127 @@ int __PHYSFS_platformMkDir(const char *path) return(1); } /* __PHYSFS_platformMkDir */ +/* + * Initialize any NT specific stuff. This includes any OS based on NT. + * + * Return zero if there was a catastrophic failure and non-zero otherwise. + */ +static int doNTInit() +{ + DWORD pathsize = 0; + char TempProfileDirectory[1]; + + /* Create a process access token handle */ + if(!OpenProcessToken(ProcessHandle, TOKEN_QUERY, &AccessTokenHandle)) + { + /* Access token is required by other win32 functions */ + return 0; + } + + /* Should fail. Will write the size of the profile path in pathsize*/ + /*!!! Second parameter can't be NULL or the function fails??? */ + if(!GetUserProfileDirectory(AccessTokenHandle, TempProfileDirectory, &pathsize)) + { + const char *temp; + temp = win32strerror(); + + /* Allocate memory for the profile directory */ + ProfileDirectory = (char *)malloc(pathsize); + BAIL_IF_MACRO(ProfileDirectory == NULL, ERR_OUT_OF_MEMORY, 0); + /* Try to get the profile directory */ + if(!GetUserProfileDirectory(AccessTokenHandle, ProfileDirectory, &pathsize)) + { + free(ProfileDirectory); + return 0; + } + } + + /* Everything initialized okay */ + return 1; +} + +/* + * Get OS info and save it. + * + * Returns non-zero if successful, otherwise it returns zero on failure. + */ +int getOSInfo(void) +{ + /* Get OS info */ + OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo); + if(!GetVersionEx(&OSVersionInfo)) + { + return 0; + } + + /* Set to TRUE if we are runnign a WinNT based OS 4.0 or greater */ + runningNT = (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && + (OSVersionInfo.dwMajorVersion > 3); + + return 1; +} + +int __PHYSFS_platformInit(void) +{ + if(!getOSInfo()) + { + return 0; + } + + /* Get Windows ProcessID associated with the current process */ + ProcessID = GetCurrentProcessId(); + /* Create a process handle associated with the current process ID */ + ProcessHandle = GetCurrentProcess(); + + if(ProcessHandle == NULL) + { + /* Process handle is required by other win32 functions */ + return 0; + } + + /* If running an NT system (NT/Win2k/XP, etc...) */ + if(runningNT) + { + if(!doNTInit()) + { + /* Error initializing NT stuff */ + return 0; + } + } + + /* It's all good */ + return 1; +} + +/* + * Uninitialize any NT specific stuff done in doNTInit(). + * + * Return zero if there was a catastrophic failure and non-zero otherwise. + */ +static int doNTDeinit() +{ + if(CloseHandle(AccessTokenHandle) != S_OK) + { + return 0; + } + + free(ProfileDirectory); + + /* It's all good */ + return 1; +} + +int __PHYSFS_platformDeinit(void) +{ + if(!doNTDeinit()) + return 0; + + if(CloseHandle(ProcessHandle) != S_OK) + return 0; + + /* It's all good */ + return 1; +} + /* end of win32.c ... */