char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) { /* * Vista and later has a new API for this, but SHGetFolderPath works there, * and apparently just wraps the new API. This is the new way to do it: * * SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE, * NULL, &wszPath); */ WCHAR path[MAX_PATH]; char *utf8 = NULL; size_t len = 0; char *retval = NULL; if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) BAIL_MACRO(PHYSFS_ERR_OS_ERROR, NULL); utf8 = unicodeToUtf8Heap(path); BAIL_IF_MACRO(!utf8, ERRPASS, NULL); len = strlen(utf8) + strlen(org) + strlen(app) + 4; retval = allocator.Malloc(len); if (!retval) { allocator.Free(utf8); BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL); } /* if */ sprintf(retval, "%s\\%s\\%s\\", utf8, org, app); return retval; } /* __PHYSFS_platformCalcPrefDir */
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) { const wchar_t* path = Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data(); wchar_t path2[1024]; wcscpy_s(path2, path); wcscat_s(path2, L"\\"); return unicodeToUtf8Heap(path2); } /* __PHYSFS_platformCalcPrefDir */
char *__PHYSFS_platformCurrentDir(void) { const wchar_t* path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); wchar_t path2[1024]; wcscpy_s(path2, path); wcscat_s(path2, L"\\"); return unicodeToUtf8Heap(path2); } /* __PHYSFS_platformCurrentDir */
static char *getExePath(void) { const wchar_t* path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); wchar_t path2[1024]; wcscpy_s(path2, path); wcscat_s(path2, L"\\"); return unicodeToUtf8Heap(path2); } /* getExePath */
char *__PHYSFS_platformCalcBaseDir(const char *argv0) { DWORD buflen = 64; LPWSTR modpath = NULL; char *retval = NULL; while (1) { DWORD rc; void *ptr; if ( (ptr = allocator.Realloc(modpath, buflen*sizeof(WCHAR))) == NULL ) { allocator.Free(modpath); BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL); } /* if */ modpath = (LPWSTR) ptr; rc = GetModuleFileNameW(NULL, modpath, buflen); if (rc == 0) { allocator.Free(modpath); BAIL_MACRO(errcodeFromWinApi(), NULL); } /* if */ if (rc < buflen) { buflen = rc; break; } /* if */ buflen *= 2; } /* while */ if (buflen > 0) /* just in case... */ { WCHAR *ptr = (modpath + buflen) - 1; while (ptr != modpath) { if (*ptr == '\\') break; ptr--; } /* while */ if ((ptr == modpath) && (*ptr != '\\')) __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR); /* oh well. */ else { *(ptr+1) = '\0'; /* chop off filename. */ retval = unicodeToUtf8Heap(modpath); } /* else */ } /* else */ allocator.Free(modpath); return retval; /* w00t. */ } /* __PHYSFS_platformCalcBaseDir */
static char *getExePath(void) { DWORD buflen = 64; LPWSTR modpath = NULL; char *retval = NULL; while (1) { DWORD rc; void *ptr; if ( !(ptr = allocator.Realloc(modpath, buflen*sizeof(WCHAR))) ) { allocator.Free(modpath); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ modpath = (LPWSTR) ptr; rc = pGetModuleFileNameW(NULL, modpath, buflen); if (rc == 0) { allocator.Free(modpath); BAIL_MACRO(winApiStrError(), NULL); } /* if */ if (rc < buflen) { buflen = rc; break; } /* if */ buflen *= 2; } /* while */ if (buflen > 0) /* just in case... */ { WCHAR *ptr = (modpath + buflen) - 1; while (ptr != modpath) { if (*ptr == '\\') break; ptr--; } /* while */ if ((ptr == modpath) && (*ptr != '\\')) __PHYSFS_setError(ERR_GETMODFN_NO_DIR); else { *(ptr + 1) = '\0'; /* chop off filename. */ retval = unicodeToUtf8Heap(modpath); } /* else */ } /* else */ allocator.Free(modpath); return(retval); /* w00t. */ } /* getExePath */
char *__PHYSFS_platformCalcUserDir(void) { typedef BOOL (WINAPI *fnGetUserProfDirW)(HANDLE, LPWSTR, LPDWORD); fnGetUserProfDirW pGetDir = NULL; HANDLE lib = NULL; HANDLE accessToken = NULL; /* Security handle to process */ char *retval = NULL; lib = LoadLibraryA("userenv.dll"); BAIL_IF_MACRO(!lib, errcodeFromWinApi(), NULL); pGetDir=(fnGetUserProfDirW) GetProcAddress(lib,"GetUserProfileDirectoryW"); GOTO_IF_MACRO(!pGetDir, errcodeFromWinApi(), done); if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &accessToken)) GOTO_MACRO(errcodeFromWinApi(), done); else { DWORD psize = 0; WCHAR dummy = 0; LPWSTR wstr = NULL; BOOL rc = 0; /* * Should fail. Will write the size of the profile path in * psize. Also note that the second parameter can't be * NULL or the function fails. */ rc = pGetDir(accessToken, &dummy, &psize); assert(!rc); /* !!! FIXME: handle this gracefully. */ (void) rc; /* Allocate memory for the profile directory */ wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR)); if (wstr != NULL) { if (pGetDir(accessToken, wstr, &psize)) { /* Make sure it ends in a dirsep. We allocated +1 for this. */ if (wstr[psize - 2] != '\\') { wstr[psize - 1] = '\\'; wstr[psize - 0] = '\0'; } /* if */ retval = unicodeToUtf8Heap(wstr); } /* if */ __PHYSFS_smallFree(wstr); } /* if */ CloseHandle(accessToken); } /* if */ done: FreeLibrary(lib); return retval; /* We made it: hit the showers. */ } /* __PHYSFS_platformCalcUserDir */
/* * Try to make use of GetUserProfileDirectoryW(), which isn't available on * some common variants of Win32. If we can't use this, we just punt and * use the physfs base dir for the user dir, too. * * On success, module-scope variable (userDir) will have a pointer to * a malloc()'d string of the user's profile dir, and a non-zero value is * returned. If we can't determine the profile dir, (userDir) will * be NULL, and zero is returned. */ static int determineUserDir(void) { if (userDir != NULL) return(1); /* already good to go. */ /* * GetUserProfileDirectoryW() is only available on NT 4.0 and later. * This means Win95/98/ME (and CE?) users have to do without, so for * them, we'll default to the base directory when we can't get the * function pointer. Since this is originally an NT API, we don't * offer a non-Unicode fallback. */ if (pGetUserProfileDirectoryW != NULL) { HANDLE accessToken = NULL; /* Security handle to process */ HANDLE processHandle = GetCurrentProcess(); if (OpenProcessToken(processHandle, TOKEN_QUERY, &accessToken)) { DWORD psize = 0; WCHAR dummy = 0; LPWSTR wstr = NULL; BOOL rc = 0; /* * Should fail. Will write the size of the profile path in * psize. Also note that the second parameter can't be * NULL or the function fails. */ rc = pGetUserProfileDirectoryW(accessToken, &dummy, &psize); assert(!rc); /* !!! FIXME: handle this gracefully. */ (void)rc; /* Allocate memory for the profile directory */ wstr = (LPWSTR) __PHYSFS_smallAlloc(psize * sizeof (WCHAR)); if (wstr != NULL) { if (pGetUserProfileDirectoryW(accessToken, wstr, &psize)) userDir = unicodeToUtf8Heap(wstr); __PHYSFS_smallFree(wstr); } /* else */ } /* if */ CloseHandle(accessToken); } /* if */ if (userDir == NULL) /* couldn't get profile for some reason. */ { /* Might just be a non-NT system; resort to the basedir. */ userDir = getExePath(); BAIL_IF_MACRO(userDir == NULL, NULL, 0); /* STILL failed?! */ } /* if */ return(1); /* We made it: hit the showers. */ } /* determineUserDir */
char *__PHYSFS_platformGetUserName(void) { DWORD bufsize = 0; char *retval = NULL; if (pGetUserNameW(NULL, &bufsize) == 0) /* This SHOULD fail. */ { LPWSTR wbuf = (LPWSTR)__PHYSFS_smallAlloc(bufsize * sizeof(WCHAR)); BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL); if (pGetUserNameW(wbuf, &bufsize) == 0) /* ?! */ __PHYSFS_setError(winApiStrError()); else retval = unicodeToUtf8Heap(wbuf); __PHYSFS_smallFree(wbuf); } /* if */ return(retval); } /* __PHYSFS_platformGetUserName */
/* * Try to make use of GetUserProfileDirectoryW(), which isn't available on * some common variants of Win32. If we can't use this, we just punt and * use the physfs base dir for the user dir, too. * * On success, module-scope variable (userDir) will have a pointer to * a malloc()'d string of the user's profile dir, and a non-zero value is * returned. If we can't determine the profile dir, (userDir) will * be NULL, and zero is returned. */ static int determineUserDir(void) { if (userDir != NULL) return(1); /* already good to go. */ const wchar_t* path = Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data(); wchar_t path2[1024]; wcscpy_s(path2, path); wcscat_s(path2, L"\\"); userDir = unicodeToUtf8Heap(path2); if (userDir == NULL) /* couldn't get profile for some reason. */ { /* Might just be a non-NT system; resort to the basedir. */ userDir = getExePath(); BAIL_IF_MACRO(userDir == NULL, NULL, 0); /* STILL failed?! */ } /* if */ return(1); /* We made it: hit the showers. */ } /* determineUserDir */
char *__PHYSFS_platformCurrentDir(void) { char *retval = NULL; WCHAR *wbuf = NULL; DWORD buflen = 0; buflen = pGetCurrentDirectoryW(buflen, NULL); wbuf = (WCHAR *) __PHYSFS_smallAlloc((buflen + 2) * sizeof (WCHAR)); BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL); pGetCurrentDirectoryW(buflen, wbuf); if (wbuf[buflen - 2] == '\\') wbuf[buflen-1] = '\0'; /* just in case... */ else { wbuf[buflen - 1] = '\\'; wbuf[buflen] = '\0'; } /* else */ retval = unicodeToUtf8Heap(wbuf); __PHYSFS_smallFree(wbuf); return(retval); } /* __PHYSFS_platformCurrentDir */
void __PHYSFS_platformEnumerateFiles(const char *dirname, PHYSFS_EnumFilesCallback callback, const char *origdir, void *callbackdata) { HANDLE dir = INVALID_HANDLE_VALUE; WIN32_FIND_DATAW entw; size_t len = strlen(dirname); char *searchPath = NULL; WCHAR *wSearchPath = NULL; /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */ searchPath = (char *)__PHYSFS_smallAlloc(len + 3); if (searchPath == NULL) return; /* Copy current dirname */ strcpy(searchPath, dirname); /* if there's no '\\' at the end of the path, stick one in there. */ if (searchPath[len - 1] != '\\') { searchPath[len++] = '\\'; searchPath[len] = '\0'; } /* if */ /* Append the "*" to the end of the string */ strcat(searchPath, "*"); UTF8_TO_UNICODE_STACK_MACRO(wSearchPath, searchPath); if (!wSearchPath) return; /* oh well. */ //dir = FindFirstFileW(wSearchPath, &entw); dir = FindFirstFileExW(wSearchPath, FindExInfoStandard, &entw, FindExSearchNameMatch, NULL, 0); __PHYSFS_smallFree(wSearchPath); __PHYSFS_smallFree(searchPath); if (dir == INVALID_HANDLE_VALUE) return; do { const DWORD attr = entw.dwFileAttributes; const DWORD tag = entw.dwReserved0; const WCHAR *fn = entw.cFileName; char *utf8; if ((fn[0] == '.') && (fn[1] == '\0')) continue; if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0')) continue; utf8 = unicodeToUtf8Heap(fn); if (utf8 != NULL) { callback(callbackdata, origdir, utf8); allocator.Free(utf8); } /* if */ } while (FindNextFileW(dir, &entw) != 0); FindClose(dir); } /* __PHYSFS_platformEnumerateFiles */
void __PHYSFS_platformEnumerateFiles(const char *dirname, int omitSymLinks, PHYSFS_EnumFilesCallback callback, const char *origdir, void *callbackdata) { const int unicode = (pFindFirstFileW != NULL) && (pFindNextFileW != NULL); HANDLE dir = INVALID_HANDLE_VALUE; WIN32_FIND_DATA ent; WIN32_FIND_DATAW entw; size_t len = strlen(dirname); char *searchPath = NULL; WCHAR *wSearchPath = NULL; char *utf8 = NULL; /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */ searchPath = (char *)__PHYSFS_smallAlloc(len + 3); if (searchPath == NULL) return; /* Copy current dirname */ strcpy(searchPath, dirname); /* if there's no '\\' at the end of the path, stick one in there. */ if (searchPath[len - 1] != '\\') { searchPath[len++] = '\\'; searchPath[len] = '\0'; } /* if */ /* Append the "*" to the end of the string */ strcat(searchPath, "*"); UTF8_TO_UNICODE_STACK_MACRO(wSearchPath, searchPath); if (wSearchPath == NULL) return; /* oh well. */ if (unicode) dir = pFindFirstFileW(wSearchPath, &entw); else { const int len = (int)(wStrLen(wSearchPath) + 1); char *cp = (char *)__PHYSFS_smallAlloc(len); if (cp != NULL) { WideCharToMultiByte(CP_ACP, 0, wSearchPath, len, cp, len, 0, 0); //dir = FindFirstFileA(cp, &ent); dir = FindFirstFileExA(cp, FindExInfoStandard, &ent, FindExSearchNameMatch, NULL, 0); __PHYSFS_smallFree(cp); } /* if */ } /* else */ __PHYSFS_smallFree(wSearchPath); __PHYSFS_smallFree(searchPath); if (dir == INVALID_HANDLE_VALUE) return; if (unicode) { do { const DWORD attr = entw.dwFileAttributes; const DWORD tag = entw.dwReserved0; const WCHAR *fn = entw.cFileName; if ((fn[0] == '.') && (fn[1] == '\0')) continue; if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0')) continue; if ((omitSymLinks) && (isSymlinkAttrs(attr, tag))) continue; utf8 = unicodeToUtf8Heap(fn); if (utf8 != NULL) { callback(callbackdata, origdir, utf8); allocator.Free(utf8); } /* if */ } while (pFindNextFileW(dir, &entw) != 0); } /* if */ else /* ANSI fallback. */ { do { const DWORD attr = ent.dwFileAttributes; const DWORD tag = ent.dwReserved0; const char *fn = ent.cFileName; if ((fn[0] == '.') && (fn[1] == '\0')) continue; if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0')) continue; if ((omitSymLinks) && (isSymlinkAttrs(attr, tag))) continue; utf8 = codepageToUtf8Heap(fn); if (utf8 != NULL) { callback(callbackdata, origdir, utf8); allocator.Free(utf8); } /* if */ } while (FindNextFileA(dir, &ent) != 0); } /* else */ FindClose(dir); } /* __PHYSFS_platformEnumerateFiles */