static int doPlatformDelete(LPWSTR wpath) { /* If filename is a folder */ if (pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) { BAIL_IF_MACRO(!pRemoveDirectoryW(wpath), winApiStrError(), 0); } /* if */ else { BAIL_IF_MACRO(!pDeleteFileW(wpath), winApiStrError(), 0); } /* else */ return(1); /* if you made it here, it worked. */ } /* doPlatformDelete */
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 | FILE_SHARE_WRITE, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);*/ fileHandle = CreateFile2(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, creation, 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 */
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_platformClose(void *opaque) { HANDLE Handle = ((WinApiFile *)opaque)->handle; BAIL_IF_MACRO(!CloseHandle(Handle), winApiStrError(), 0); allocator.Free(opaque); return(1); } /* __PHYSFS_platformClose */
int __PHYSFS_platformFlush(void *opaque) { WinApiFile *fh = ((WinApiFile *)opaque); if (!fh->readonly) BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), winApiStrError(), 0); return(1); } /* __PHYSFS_platformFlush */
/* * Get OS info and save the important parts. * * Returns non-zero if successful, otherwise it returns zero on failure. */ static int getOSInfo(void) { OSVERSIONINFO osVerInfo; /* Information about the OS */ osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo); BAIL_IF_MACRO(!GetVersionEx(&osVerInfo), winApiStrError(), 0); osHasUnicode = (osVerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); return(1); } /* getOSInfo */
static int doPlatformExists(LPWSTR wpath) { BAIL_IF_MACRO ( pGetFileAttributesW(wpath) == PHYSFS_INVALID_FILE_ATTRIBUTES, winApiStrError(), 0 ); return(1); } /* doPlatformExists */
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 */
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 */
static int doPlatformDelete(LPWSTR wpath) { /* If filename is a folder */ int isdir = 0; //if (pGetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY) WIN32_FILE_ATTRIBUTE_DATA file_info; const BOOL res = GetFileAttributesExW(wpath, GetFileExInfoStandard, &file_info); if (res) { isdir = (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); } if (isdir) { BAIL_IF_MACRO(!pRemoveDirectoryW(wpath), winApiStrError(), 0); } /* if */ else { BAIL_IF_MACRO(!pDeleteFileW(wpath), winApiStrError(), 0); } /* else */ return(1); /* if you made it here, it worked. */ } /* doPlatformDelete */
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 */
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 char *err = winApiStrError(); CloseHandle(h); allocator.Free(retval); BAIL_MACRO(err, NULL); } /* if */ } /* if */ return(retval); } /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer, PHYSFS_uint32 size, PHYSFS_uint32 count) { HANDLE Handle = ((WinApiFile *)opaque)->handle; DWORD CountOfBytesWritten; PHYSFS_sint64 retval; /* Read data from the file */ /* !!! FIXME: uint32 might be a greater # than DWORD */ if (!WriteFile(Handle, buffer, count * size, &CountOfBytesWritten, NULL)) { BAIL_MACRO(winApiStrError(), -1); } /* if */ else { /* Return the number of "objects" read. */ /* !!! FIXME: What if not the right number of bytes was written? */ retval = CountOfBytesWritten / size; } /* else */ return(retval); } /* __PHYSFS_platformWrite */
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(winApiStrError(), -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 */
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(winApiStrError(), -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 */
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; /* * !!! FIXME: MSDN: "Windows Me/98/95: If the pointer * !!! FIXME: lpDistanceToMoveHigh is not NULL, then it must * !!! FIXME: point to either 0, INVALID_SET_FILE_POINTER, or * !!! FIXME: the sign extension of the value of lDistanceToMove. * !!! FIXME: Any other value will be rejected." */ /* 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(winApiStrError(), 0); } /* if */ return(1); /* No error occured */ } /* __PHYSFS_platformSeek */