Пример #1
0
static PHYSFS_sint64 FileTimeToPhysfsTime(const FILETIME *ft)
{
	SYSTEMTIME st_utc;
	SYSTEMTIME st_localtz;
	TIME_ZONE_INFORMATION tzi;
	DWORD tzid;
	PHYSFS_sint64 retval;
	struct tm tm;
	BOOL rc;

	BAIL_IF_MACRO(!FileTimeToSystemTime(ft, &st_utc), errcodeFromWinApi(), -1);
	tzid = GetTimeZoneInformation(&tzi);
	BAIL_IF_MACRO(tzid == TIME_ZONE_ID_INVALID, errcodeFromWinApi(), -1);
	rc = SystemTimeToTzSpecificLocalTime(&tzi, &st_utc, &st_localtz);
	BAIL_IF_MACRO(!rc, errcodeFromWinApi(), -1);

	/* Convert to a format that mktime() can grok... */
	tm.tm_sec = st_localtz.wSecond;
	tm.tm_min = st_localtz.wMinute;
	tm.tm_hour = st_localtz.wHour;
	tm.tm_mday = st_localtz.wDay;
	tm.tm_mon = st_localtz.wMonth - 1;
	tm.tm_year = st_localtz.wYear - 1900;
	tm.tm_wday = -1 /*st_localtz.wDayOfWeek*/;
	tm.tm_yday = -1;
	tm.tm_isdst = -1;

	/* Convert to a format PhysicsFS can grok... */
	retval = (PHYSFS_sint64)mktime(&tm);
	BAIL_IF_MACRO(retval == -1, PHYSFS_ERR_OS_ERROR, -1);
	return retval;
} /* FileTimeToPhysfsTime */
Пример #2
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 */
Пример #3
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 */
Пример #4
0
static int doPlatformDelete(LPWSTR wpath)
{
    const int isdir = (GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY);
    const BOOL rc = (isdir) ? RemoveDirectoryW(wpath) : DeleteFileW(wpath);
    BAIL_IF_MACRO(!rc, errcodeFromWinApi(), 0);
    return 1;   /* if you made it here, it worked. */
} /* doPlatformDelete */
Пример #5
0
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
{
    HANDLE Handle = ((WinApiFile *) opaque)->handle;
    LONG HighOrderPos;
    PLONG pHighOrderPos;
    DWORD rc;

    /* Get the high order 32-bits of the position */
    HighOrderPos = HIGHORDER_UINT64(pos);

    /*
     * MSDN: "If you do not need the high-order 32 bits, this
     *         pointer must be set to NULL."
     */
    pHighOrderPos = (HighOrderPos) ? &HighOrderPos : NULL;

    /* Move pointer "pos" count from start of file */
    rc = SetFilePointer(Handle, LOWORDER_UINT64(pos),
                        pHighOrderPos, FILE_BEGIN);

    if ( (rc == PHYSFS_INVALID_SET_FILE_POINTER) &&
         (GetLastError() != NO_ERROR) )
    {
        BAIL_MACRO(errcodeFromWinApi(), 0);
    } /* if */

    return 1;  /* No error occured */
} /* __PHYSFS_platformSeek */
Пример #6
0
int __PHYSFS_platformFlush(void *opaque)
{
	WinApiFile *fh = ((WinApiFile *)opaque);
	if (!fh->readonly)
		BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), errcodeFromWinApi(), 0);

	return 1;
} /* __PHYSFS_platformFlush */
Пример #7
0
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 */
Пример #8
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 */
Пример #9
0
static int doPlatformDelete(LPWSTR wpath)
{
	//const int isdir = (GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY);
	int isdir = 0;
	WIN32_FILE_ATTRIBUTE_DATA file_info;
	const BOOL res = GetFileAttributesEx(wpath, GetFileExInfoStandard, &file_info);
	if (res) {
		isdir = (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
	}

	const BOOL rc = (isdir) ? RemoveDirectoryW(wpath) : DeleteFileW(wpath);
	BAIL_IF_MACRO(!rc, errcodeFromWinApi(), 0);
	return 1;   /* if you made it here, it worked. */
} /* doPlatformDelete */
Пример #10
0
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
{
	HANDLE Handle = ((WinApiFile *)opaque)->handle;
	BOOL rc;

	LARGE_INTEGER li;
	li.LowPart = LOWORDER_UINT64(pos);
	li.HighPart = HIGHORDER_UINT64(pos);

	rc = SetFilePointerEx(Handle, li, NULL, FILE_BEGIN);

	if (!rc && (GetLastError() != NO_ERROR))
	{
		BAIL_MACRO(errcodeFromWinApi(), 0);
	} /* if */

	return 1;  /* No error occured */
} /* __PHYSFS_platformSeek */
Пример #11
0
void *__PHYSFS_platformOpenAppend(const char *filename)
{
    void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
    if (retval != NULL)
    {
        HANDLE h = ((WinApiFile *) retval)->handle;
        DWORD rc = SetFilePointer(h, 0, NULL, FILE_END);
        if (rc == PHYSFS_INVALID_SET_FILE_POINTER)
        {
            const PHYSFS_ErrorCode err = errcodeFromWinApi();
            CloseHandle(h);
            allocator.Free(retval);
            BAIL_MACRO(err, NULL);
        } /* if */
    } /* if */

    return retval;
} /* __PHYSFS_platformOpenAppend */
Пример #12
0
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
{
	HANDLE Handle = ((WinApiFile *)opaque)->handle;
	PHYSFS_sint64 totalRead = 0;

	if (!__PHYSFS_ui64FitsAddressSpace(len))
		BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);

	while (len > 0)
	{
		const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD)len;
		DWORD numRead = 0;
		if (!ReadFile(Handle, buf, thislen, &numRead, NULL))
			BAIL_MACRO(errcodeFromWinApi(), -1);
		len -= (PHYSFS_uint64)numRead;
		totalRead += (PHYSFS_sint64)numRead;
		if (numRead != thislen)
			break;
	} /* while */
	
	return totalRead;
} /* __PHYSFS_platformRead */
Пример #13
0
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
{
    HANDLE Handle = ((WinApiFile *) opaque)->handle;
    DWORD SizeHigh;
    DWORD SizeLow;
    PHYSFS_sint64 retval;

    SizeLow = GetFileSize(Handle, &SizeHigh);
    if ( (SizeLow == PHYSFS_INVALID_SET_FILE_POINTER) &&
         (GetLastError() != NO_ERROR) )
    {
        BAIL_MACRO(errcodeFromWinApi(), -1);
    } /* if */
    else
    {
        /* Combine the high/low order to create the 64-bit position value */
        retval = (((PHYSFS_uint64) SizeHigh) << 32) | SizeLow;
        assert(retval >= 0);
    } /* else */

    return retval;
} /* __PHYSFS_platformFileLength */
Пример #14
0
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
{
	HANDLE Handle = ((WinApiFile *)opaque)->handle;
	PHYSFS_sint64 retval;
	BOOL rc;

	LARGE_INTEGER zero;
	zero.QuadPart = 0;
	LARGE_INTEGER out;

	rc = SetFilePointerEx(Handle, zero, &out, FILE_CURRENT);
	if (!rc)
	{
		BAIL_MACRO(errcodeFromWinApi(), -1);
	} /* if */
	else
	{
		retval = out.QuadPart;
		assert(retval >= 0);
	} /* else */

	return retval;
} /* __PHYSFS_platformTell */
Пример #15
0
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
	PHYSFS_uint64 len)
{
	HANDLE Handle = ((WinApiFile *)opaque)->handle;
	PHYSFS_sint64 totalWritten = 0;

	if (!__PHYSFS_ui64FitsAddressSpace(len))
		BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);

	while (len > 0)
	{
		const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD)len;
		DWORD numWritten = 0;
		if (!WriteFile(Handle, buffer, thislen, &numWritten, NULL))
			BAIL_MACRO(errcodeFromWinApi(), -1);
		len -= (PHYSFS_uint64)numWritten;
		totalWritten += (PHYSFS_sint64)numWritten;
		if (numWritten != thislen)
			break;
	} /* while */

	return totalWritten;
} /* __PHYSFS_platformWrite */
Пример #16
0
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
{
    HANDLE Handle = ((WinApiFile *) opaque)->handle;
    LONG HighPos = 0;
    DWORD LowPos;
    PHYSFS_sint64 retval;

    /* Get current position */
    LowPos = SetFilePointer(Handle, 0, &HighPos, FILE_CURRENT);
    if ( (LowPos == PHYSFS_INVALID_SET_FILE_POINTER) &&
         (GetLastError() != NO_ERROR) )
    {
        BAIL_MACRO(errcodeFromWinApi(), -1);
    } /* if */
    else
    {
        /* Combine the high/low order to create the 64-bit position value */
        retval = (((PHYSFS_uint64) HighPos) << 32) | LowPos;
        assert(retval >= 0);
    } /* else */

    return retval;
} /* __PHYSFS_platformTell */