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 */
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 */
PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname) { PHYSFS_sint64 retval = -1; WIN32_FILE_ATTRIBUTE_DATA attrData; memset(&attrData, '\0', sizeof (attrData)); /* GetFileAttributesEx didn't show up until Win98 and NT4. */ if (pGetFileAttributesEx != NULL) { if (pGetFileAttributesEx(fname, GetFileExInfoStandard, &attrData)) { /* 0 return value indicates an error or not supported */ if ( (attrData.ftLastWriteTime.dwHighDateTime != 0) || (attrData.ftLastWriteTime.dwLowDateTime != 0) ) { retval = FileTimeToPhysfsTime(&attrData.ftLastWriteTime); } /* if */ } /* 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; win32file *f = (win32file *) __PHYSFS_platformOpenRead(fname); BAIL_IF_MACRO(f == NULL, NULL, -1) rc = GetFileTime(f->handle, NULL, NULL, &ft); err = win32strerror(); CloseHandle(f->handle); free(f); BAIL_IF_MACRO(!rc, err, -1); retval = FileTimeToPhysfsTime(&ft); } /* if */ return(retval); } /* __PHYSFS_platformGetLastModTime */