Exemple #1
0
static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
{
	HANDLE fileh;
	WinApiFile *retval;
	WCHAR *wfname;

	UTF8_TO_UNICODE_STACK_MACRO(wfname, fname);
	BAIL_IF_MACRO(!wfname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
	//fileh = CreateFileW(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
	fileh = CreateFile2(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, creation, NULL);
	__PHYSFS_smallFree(wfname);

	BAIL_IF_MACRO(fileh == INVALID_HANDLE_VALUE, errcodeFromWinApi(), NULL);

	retval = (WinApiFile *)allocator.Malloc(sizeof(WinApiFile));
	if (!retval)
	{
		CloseHandle(fileh);
		BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
	} /* if */

	retval->readonly = rdonly;
	retval->handle = fileh;
	return retval;
} /* doOpen */
Exemple #2
0
int __PHYSFS_platformIsSymLink(const char *fname)
{
	/* !!! FIXME:
	* Windows Vista can have NTFS symlinks. Can older Windows releases have
	*  them when talking to a network file server? What happens when you
	*  mount a NTFS partition on XP that was plugged into a Vista install
	*  that made a symlink?
	*/

	int retval = 0;
	LPWSTR wpath;
	HANDLE dir;
	WIN32_FIND_DATAW entw;

	/* no unicode entry points? Probably no symlinks. */
	BAIL_IF_MACRO(pFindFirstFileW == NULL, NULL, 0);

	UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
	BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);

	/* !!! FIXME: filter wildcard chars? */
	dir = pFindFirstFileW(wpath, &entw);
	if (dir != INVALID_HANDLE_VALUE)
	{
		retval = isSymlinkAttrs(entw.dwFileAttributes, entw.dwReserved0);
		FindClose(dir);
	} /* if */

	__PHYSFS_smallFree(wpath);
	return(retval);
} /* __PHYSFS_platformIsSymlink */
Exemple #3
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 */
static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
{
    HANDLE fileHandle;
    WinApiFile *retval;
    WCHAR *wfname;

    UTF8_TO_UNICODE_STACK_MACRO(wfname, fname);
    BAIL_IF_MACRO(wfname == NULL, ERR_OUT_OF_MEMORY, NULL);
    fileHandle = pCreateFileW(wfname, mode, FILE_SHARE_READ, NULL,
                              creation, FILE_ATTRIBUTE_NORMAL, NULL);
    __PHYSFS_smallFree(wfname);

    BAIL_IF_MACRO
    (
        fileHandle == INVALID_HANDLE_VALUE,
        winApiStrError(), NULL
    );

    retval = (WinApiFile *) allocator.Malloc(sizeof (WinApiFile));
    if (retval == NULL)
    {
        CloseHandle(fileHandle);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
    } /* if */

    retval->readonly = rdonly;
    retval->handle = fileHandle;
    return(retval);
} /* doOpen */
Exemple #5
0
int __PHYSFS_platformDelete(const char *path)
{
	int retval = 0;
	LPWSTR wpath = NULL;
	UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
	BAIL_IF_MACRO(!wpath, PHYSFS_ERR_OUT_OF_MEMORY, 0);
	retval = doPlatformDelete(wpath);
	__PHYSFS_smallFree(wpath);
	return retval;
} /* __PHYSFS_platformDelete */
Exemple #6
0
int __PHYSFS_platformMkDir(const char *path)
{
	WCHAR *wpath;
	DWORD rc;
	UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
	rc = CreateDirectoryW(wpath, NULL);
	__PHYSFS_smallFree(wpath);
	BAIL_IF_MACRO(rc == 0, errcodeFromWinApi(), 0);
	return 1;
} /* __PHYSFS_platformMkDir */
Exemple #7
0
int __PHYSFS_platformMkDir(const char *path)
{
	WCHAR *wpath;
	DWORD rc;
	UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
	rc = pCreateDirectoryW(wpath, NULL);
	__PHYSFS_smallFree(wpath);
	BAIL_IF_MACRO(rc == 0, winApiStrError(), 0);
	return(1);
} /* __PHYSFS_platformMkDir */
Exemple #8
0
int __PHYSFS_platformExists(const char *fname)
{
	int retval = 0;
	LPWSTR wpath;
	UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
	BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
	retval = doPlatformExists(wpath);
	__PHYSFS_smallFree(wpath);
	return(retval);
} /* __PHYSFS_platformExists */
Exemple #9
0
int __PHYSFS_platformIsDirectory(const char *fname)
{
    int retval = 0;
    LPWSTR wpath;
    UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
    BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
    retval = ((pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) != 0);
    __PHYSFS_smallFree(wpath);
    return(retval);
} /* __PHYSFS_platformIsDirectory */
Exemple #10
0
int __PHYSFS_platformIsDirectory(const char *fname)
{
	int retval = 0;
	LPWSTR wpath;
	UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
	BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, 0);
	//retval = ((pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) != 0);
	WIN32_FILE_ATTRIBUTE_DATA file_info;
	const BOOL res = GetFileAttributesExW(wpath, GetFileExInfoStandard, &file_info);
	if (res) {
		retval = ((file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
	}

	__PHYSFS_smallFree(wpath);
	return(retval);
} /* __PHYSFS_platformIsDirectory */
Exemple #11
0
int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *stat)
{
    WIN32_FILE_ATTRIBUTE_DATA winstat;
    WCHAR *wstr = NULL;
    DWORD err = 0;
    BOOL rc = 0;

    UTF8_TO_UNICODE_STACK_MACRO(wstr, filename);
    BAIL_IF_MACRO(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
    rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
    err = (!rc) ? GetLastError() : 0;
    *exists = ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND));
    __PHYSFS_smallFree(wstr);
    BAIL_IF_MACRO(!rc, errcodeFromWinApiError(err), 0);

    stat->modtime = FileTimeToPhysfsTime(&winstat.ftLastWriteTime);
    stat->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
    stat->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);

    if(winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
        stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
        stat->filesize = 0;
    } /* if */

    else if(winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
    {
        /* !!! FIXME: what are reparse points? */
        stat->filetype = PHYSFS_FILETYPE_OTHER;
        /* !!! FIXME: don't rely on this */
        stat->filesize = 0;
    } /* else if */

    /* !!! FIXME: check for symlinks on Vista. */

    else
    {
        stat->filetype = PHYSFS_FILETYPE_REGULAR;
        stat->filesize = (((PHYSFS_uint64) winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow;
    } /* else */

    stat->readonly = ((winstat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);

    return 1;
} /* __PHYSFS_platformStat */
Exemple #12
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 */
Exemple #13
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 */