Example #1
0
PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname)
{
	PHYSFS_sint64 retval = -1;
	WIN32_FILE_ATTRIBUTE_DATA attr;
	int rc = 0;

	memset(&attr, '\0', sizeof(attr));

	/* GetFileAttributesEx didn't show up until Win98 and NT4. */
	if ((pGetFileAttributesExW != NULL) || (pGetFileAttributesExA != NULL))
	{
		WCHAR *wstr;
		UTF8_TO_UNICODE_STACK_MACRO(wstr, fname);
		if (wstr != NULL) /* if NULL, maybe the fallback will work. */
		{
			if (pGetFileAttributesExW != NULL)  /* NT/XP/Vista/etc system. */
				rc = pGetFileAttributesExW(wstr, GetFileExInfoStandard, &attr);
			else  /* Win98/ME system */
			{
				const int len = (int)(wStrLen(wstr) + 1);
				char *cp = (char *)__PHYSFS_smallAlloc(len);
				if (cp != NULL)
				{
					WideCharToMultiByte(CP_ACP, 0, wstr, len, cp, len, 0, 0);
					rc = pGetFileAttributesExA(cp, GetFileExInfoStandard, &attr);
					__PHYSFS_smallFree(cp);
				} /* if */
			} /* else */
			__PHYSFS_smallFree(wstr);
		} /* if */
	} /* if */

	if (rc)  /* had API entry point and it worked. */
	{
		/* 0 return value indicates an error or not supported */
		if ((attr.ftLastWriteTime.dwHighDateTime != 0) ||
			(attr.ftLastWriteTime.dwLowDateTime != 0))
		{
			retval = FileTimeToPhysfsTime(&attr.ftLastWriteTime);
		} /* if */
	} /* if */

	  /* GetFileTime() has been in the Win32 API since the start. */
	if (retval == -1)  /* try a fallback... */
	{
		FILETIME ft;
		BOOL rc;
		const char *err;
		WinApiFile *f = (WinApiFile *)__PHYSFS_platformOpenRead(fname);
		BAIL_IF_MACRO(f == NULL, NULL, -1)
			rc = GetFileTime(f->handle, NULL, NULL, &ft);
		err = winApiStrError();
		CloseHandle(f->handle);
		allocator.Free(f);
		BAIL_IF_MACRO(!rc, err, -1);
		retval = FileTimeToPhysfsTime(&ft);
	} /* if */

	return(retval);
} /* __PHYSFS_platformGetLastModTime */
Example #2
0
static BOOL WINAPI fallbackDeleteFileW(LPCWSTR fname)
{
	BOOL retval = 0;
	const int buflen = (int)(wStrLen(fname) + 1);
	char *cpstr = (char *)__PHYSFS_smallAlloc(buflen);
	WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
	retval = DeleteFileA(cpstr);
	__PHYSFS_smallFree(cpstr);
	return(retval);
} /* fallbackDeleteFileW */
Example #3
0
static BOOL WINAPI fallbackGetUserNameW(LPWSTR buf, LPDWORD len)
{
    const DWORD cplen = *len;
    char *cpstr = __PHYSFS_smallAlloc(cplen);
    BOOL retval = GetUserNameA(cpstr, len);
    if (buf != NULL)
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpstr, cplen, buf, *len);
    __PHYSFS_smallFree(cpstr);
    return(retval);
} /* fallbackGetUserNameW */
Example #4
0
static BOOL WINAPI fallbackRemoveDirectoryW(LPCWSTR dname)
{
	BOOL retval = 0;
	const int buflen = (int)(wStrLen(dname) + 1);
	char *cpstr = (char *)__PHYSFS_smallAlloc(buflen);
	WideCharToMultiByte(CP_ACP, 0, dname, buflen, cpstr, buflen, NULL, NULL);
	retval = RemoveDirectoryA(cpstr);
	__PHYSFS_smallFree(cpstr);
	return(retval);
} /* fallbackRemoveDirectoryW */
Example #5
0
static DWORD WINAPI fallbackGetFileAttributesW(LPCWSTR fname)
{
    DWORD retval = 0;
    const int buflen = (int) (wStrLen(fname) + 1);
    char *cpstr = (char *) __PHYSFS_smallAlloc(buflen);
    WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
    retval = GetFileAttributesA(cpstr);
    __PHYSFS_smallFree(cpstr);
    return(retval);
} /* fallbackGetFileAttributesW */
Example #6
0
static DWORD WINAPI fallbackGetModuleFileNameW(HMODULE hMod, LPWCH lpBuf,
	DWORD nSize)
{
	char *cpbuf = (char *)__PHYSFS_smallAlloc(nSize);
	DWORD retval = GetModuleFileNameA(hMod, cpbuf, nSize);
	if (retval > 0)
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpbuf, retval, lpBuf, nSize);
	__PHYSFS_smallFree(cpbuf);
	return(retval);
} /* fallbackGetModuleFileNameW */
Example #7
0
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 */
Example #8
0
/*
 * 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 */
Example #9
0
/*
 * Moved to seperate function so we can use alloca then immediately throw
 *  away the allocated stack space...
 */
static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
                           const char *odir, const char *str, PHYSFS_sint32 ln)
{
    char *newstr = __PHYSFS_smallAlloc(ln + 1);
    if (newstr == NULL)
        return;

    memcpy(newstr, str, ln);
    newstr[ln] = '\0';
    cb(callbackdata, odir, newstr);
    __PHYSFS_smallFree(newstr);
} /* doEnumCallback */
Example #10
0
static DWORD WINAPI fallbackFormatMessageW(DWORD dwFlags, LPCVOID lpSource,
	DWORD dwMessageId, DWORD dwLangId,
	LPWSTR lpBuf, DWORD nSize,
	va_list *Arguments)
{
	char *cpbuf = (char *)__PHYSFS_smallAlloc(nSize);
	DWORD retval = FormatMessageA(dwFlags, lpSource, dwMessageId, dwLangId,
		cpbuf, nSize, Arguments);
	if (retval > 0)
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpbuf, retval, lpBuf, nSize);
	__PHYSFS_smallFree(cpbuf);
	return(retval);
} /* fallbackFormatMessageW */
Example #11
0
static DWORD WINAPI fallbackGetCurrentDirectoryW(DWORD buflen, LPWSTR buf)
{
    DWORD retval = 0;
    char *cpbuf = NULL;
    if (buf != NULL)
        cpbuf = (char *) __PHYSFS_smallAlloc(buflen);
    retval = GetCurrentDirectoryA(buflen, cpbuf);
    if (cpbuf != NULL)
    {
        MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,cpbuf,retval,buf,buflen);
        __PHYSFS_smallFree(cpbuf);
    } /* if */
    return(retval);
} /* fallbackGetCurrentDirectoryW */
Example #12
0
static HANDLE WINAPI fallbackCreateFileW(LPCWSTR fname,
	DWORD dwDesiredAccess, DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttrs,
	DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttrs, HANDLE hTemplFile)
{
	HANDLE retval;
	const int buflen = (int)(wStrLen(fname) + 1);
	char *cpstr = (char *)__PHYSFS_smallAlloc(buflen);
	WideCharToMultiByte(CP_ACP, 0, fname, buflen, cpstr, buflen, NULL, NULL);
	//retval = CreateFileA(cpstr, dwDesiredAccess, dwShareMode, lpSecurityAttrs, dwCreationDisposition, dwFlagsAndAttrs, hTemplFile);
	retval = CreateFile2(fname, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
	__PHYSFS_smallFree(cpstr);
	return(retval);
} /* fallbackCreateFileW */
Example #13
0
static char *codepageToUtf8Heap(const char *cpstr)
{
	char *retval = NULL;
	if (cpstr != NULL)
	{
		const int len = (int)(strlen(cpstr) + 1);
		WCHAR *wbuf = (WCHAR *)__PHYSFS_smallAlloc(len * sizeof(WCHAR));
		BAIL_IF_MACRO(wbuf == NULL, ERR_OUT_OF_MEMORY, NULL);
		MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cpstr, len, wbuf, len);
		retval = (char *)allocator.Malloc(len * 4);
		if (retval == NULL)
			__PHYSFS_setError(ERR_OUT_OF_MEMORY);
		else
			PHYSFS_utf8FromUcs2((const PHYSFS_uint16*)wbuf, retval, len * 4);
		__PHYSFS_smallFree(wbuf);
	} /* if */
	return(retval);
} /* codepageToUtf8Heap */
Example #14
0
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 */
Example #15
0
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 */
Example #16
0
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 */
Example #17
0
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
    char *retval = NULL;
    const char *envr = NULL;

    /* Try to avoid using argv0 unless forced to. Try system-specific stuff. */
    
    #if PHYSFS_PLATFORM_FREEBSD
    {
        char fullpath[PATH_MAX];
        size_t buflen = sizeof (fullpath);
        int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
        if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1)
            retval = __PHYSFS_strdup(fullpath);
    }
    #elif PHYSFS_PLATFORM_SOLARIS
    {
        const char *path = getexecname();
        if ((path != NULL) && (path[0] == '/'))  /* must be absolute path... */
            retval = __PHYSFS_strdup(path);
    }
    #endif

    if (retval)
        return retval;   /* already got it. */

    /* If there's a Linux-like /proc filesystem, you can get the full path to
     *  the current process from a symlink in there.
     */

    if (access("/proc", F_OK) == 0)
    {
        retval = readSymLink("/proc/self/exe");
        if (!retval) retval = readSymLink("/proc/curproc/file");
        if (!retval) retval = readSymLink("/proc/curproc/exe");
        if (retval == NULL)
        {
            /* older kernels don't have /proc/self ... try PID version... */
            const unsigned long long pid = (unsigned long long) getpid();
            char path[64];
            const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
            if ( (rc > 0) && (rc < sizeof(path)) )
                retval = readSymLink(path);
        } /* if */
    } /* if */

    if (retval != NULL)  /* chop off filename. */
    {
        char *ptr = strrchr(retval, '/');
        if (ptr != NULL)
            *(ptr+1) = '\0';
        else  /* shouldn't happen, but just in case... */
        {
            physfs_alloc.Free(retval);
            retval = NULL;
        } /* else */
    } /* if */

    /* No /proc/self/exe, etc, but we have an argv[0] we can parse? */
    if ((retval == NULL) && (argv0 != NULL))
    {
        /* fast path: default behaviour can handle this. */
        if (strchr(argv0, '/') != NULL)
            return NULL;  /* higher level parses out real path from argv0. */

        /* If there's no dirsep on argv0, then look through $PATH for it. */
        envr = getenv("PATH");
        if (envr != NULL)
        {
            char *path = (char *) __PHYSFS_smallAlloc(strlen(envr) + 1);
            BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
            strcpy(path, envr);
            retval = findBinaryInPath(argv0, path);
            __PHYSFS_smallFree(path);
        } /* if */
    } /* if */

    if (retval != NULL)
    {
        /* try to shrink buffer... */
        char *ptr = (char *) physfs_alloc.Realloc(retval, strlen(retval) + 1);
        if (ptr != NULL)
            retval = ptr;  /* oh well if it failed. */
    } /* if */

    return retval;
} /* __PHYSFS_platformCalcBaseDir */
Example #18
0
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 */