From 7d08cd623208243ecf63be24a8d24dccc886d37e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 22 Nov 2002 06:17:59 +0000 Subject: [PATCH] Initial add. --- platform/pocketpc.c | 632 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 632 insertions(+) create mode 100644 platform/pocketpc.c diff --git a/platform/pocketpc.c b/platform/pocketpc.c new file mode 100644 index 00000000..3561e9d0 --- /dev/null +++ b/platform/pocketpc.c @@ -0,0 +1,632 @@ +/* + * Skeleton platform-dependent support routines for PhysicsFS. + * + * Please see the file LICENSE in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include + +#define __PHYSICSFS_INTERNAL__ +#include "physfs_internal.h" + +#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF +#define INVALID_SET_FILE_POINTER 0xFFFFFFFF +typedef struct +{ + HANDLE handle; + int readonly; +} winCEfile; + + +const char *__PHYSFS_platformDirSeparator = "\\"; + +/* + * Figure out what the last failing Win32 API call was, and + * generate a human-readable string for the error message. + * + * The return value is a static buffer that is overwritten with + * each call to this function. + */ +static const char *win32strerror(void) +{ + static TCHAR msgbuf[255]; + TCHAR *ptr = msgbuf; + + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + msgbuf, + sizeof (msgbuf) / sizeof (TCHAR), + NULL + ); + + /* chop off newlines. */ + for (ptr = msgbuf; *ptr; ptr++) + { + if ((*ptr == '\n') || (*ptr == '\r')) + { + *ptr = ' '; + break; + } /* if */ + } /* for */ + + return((const char *) msgbuf); +} /* win32strerror */ + + +static char *UnicodeToAsc(const wchar_t *w_str) +{ + char *str=NULL; + + if(w_str!=NULL) + { + int len=wcslen(w_str)+1; + str=(char *)malloc(len); + + if(WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL)==0) + { //Conversion failed + free(str); + return NULL; + } + else + { //Conversion successful + return(str); + } + + } + else + { //Given NULL string + return NULL; + } +} + +static wchar_t *AscToUnicode(const char *str) +{ + wchar_t *w_str=NULL; + if(str!=NULL) + { + int len=strlen(str)+1; + w_str=(wchar_t *)malloc(sizeof(wchar_t)*len); + if(MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len)==0) + { + free(w_str); + return NULL; + } + else + { + return(w_str); + } + } + else + { + return NULL; + } +} + + +int __PHYSFS_platformInit(void) +{ + return(1); /* always succeed. */ +} /* __PHYSFS_platformInit */ + + +int __PHYSFS_platformDeinit(void) +{ + return(1); /* always succeed. */ +} /* __PHYSFS_platformDeinit */ + + +char **__PHYSFS_platformDetectAvailableCDs(void) +{ + BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL); +} /* __PHYSFS_platformDetectAvailableCDs */ + + +char *__PHYSFS_platformCalcBaseDir(const char *argv0) +{ + return("\\"); +// BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL); +} /* __PHYSFS_platformCalcBaseDir */ + + +char *__PHYSFS_platformGetUserName(void) +{ + BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL); +} /* __PHYSFS_platformGetUserName */ + + +char *__PHYSFS_platformGetUserDir(void) +{ + return("\\"); + BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL); +} /* __PHYSFS_platformGetUserDir */ + + +PHYSFS_uint64 __PHYSFS_platformGetThreadID(void) +{ + return(1); /* single threaded. */ +} /* __PHYSFS_platformGetThreadID */ + + +int __PHYSFS_platformStricmp(const char *x, const char *y) +{ + const char *p1 = x, *p2 = y; + int r = 0; + + while((*p1) && (*p2) && (toupper(*p1++) == toupper(*p2++))) ++r; + + r = (!((*p1) || (*p2)) ? (0) : ((toupper(*p1) > toupper(*p2)) ? + (r + 1) : -(r + 1))); + + return(r); + +} /* __PHYSFS_platformStricmp */ + + +int __PHYSFS_platformExists(const char *fname) +{ + int retval=0; + + wchar_t *w_fname=AscToUnicode(fname); + + if(w_fname!=NULL) + { + retval=(GetFileAttributes(w_fname) != INVALID_FILE_ATTRIBUTES); + free(w_fname); + } + + return(retval); +} /* __PHYSFS_platformExists */ + + +int __PHYSFS_platformIsSymLink(const char *fname) +{ + BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0); +} /* __PHYSFS_platformIsSymlink */ + + +int __PHYSFS_platformIsDirectory(const char *fname) +{ + int retval=0; + + wchar_t *w_fname=AscToUnicode(fname); + + if(w_fname!=NULL) + { + retval=((GetFileAttributes(w_fname) & FILE_ATTRIBUTE_DIRECTORY) != 0); + free(w_fname); + } + + return(retval); +} /* __PHYSFS_platformIsDirectory */ + + +char *__PHYSFS_platformCvtToDependent(const char *prepend, + const char *dirName, + const char *append) +{ + int len = ((prepend) ? strlen(prepend) : 0) + + ((append) ? strlen(append) : 0) + + strlen(dirName) + 1; + char *retval = malloc(len); + char *p; + + BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); + + if (prepend) + strcpy(retval, prepend); + else + retval[0] = '\0'; + + strcat(retval, dirName); + + if (append) + strcat(retval, append); + + for (p = strchr(retval, '/'); p != NULL; p = strchr(p + 1, '/')) + *p = '\\'; + + return(retval); +} /* __PHYSFS_platformCvtToDependent */ + + +void __PHYSFS_platformTimeslice(void) +{ + Sleep(10); +} /* __PHYSFS_platformTimeslice */ + + +LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, + int omitSymLinks) +{ + LinkedStringList *retval = NULL; + LinkedStringList *l = NULL; + LinkedStringList *prev = NULL; + HANDLE dir; + WIN32_FIND_DATA ent; + char *SearchPath; + wchar_t *w_SearchPath; + size_t len = strlen(dirname); + + /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */ + SearchPath = (char *) alloca(len + 3); + BAIL_IF_MACRO(SearchPath == NULL, ERR_OUT_OF_MEMORY, NULL); + + /* 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, "*"); + + w_SearchPath=AscToUnicode(SearchPath); + + dir = FindFirstFile(w_SearchPath, &ent); + free(w_SearchPath); + free(SearchPath); + + if(dir == INVALID_HANDLE_VALUE) + { + return NULL; + } + + do + { + if (wcscmp(ent.cFileName, L".") == 0) + continue; + + if (wcscmp(ent.cFileName, L"..") == 0) + continue; + + l = (LinkedStringList *) malloc(sizeof (LinkedStringList)); + if (l == NULL) + break; + + l->str=UnicodeToAsc(ent.cFileName); + + if (l->str == NULL) + { + free(l); + break; + } + + + if (retval == NULL) + retval = l; + else + prev->next = l; + + prev = l; + l->next = NULL; + } while (FindNextFile(dir, &ent) != 0); + + FindClose(dir); + return(retval); +} /* __PHYSFS_platformEnumerateFiles */ + + +char *__PHYSFS_platformCurrentDir(void) +{ + return("\\"); +} /* __PHYSFS_platformCurrentDir */ + + +char *__PHYSFS_platformRealPath(const char *path) +{ + char *retval=(char *)malloc(strlen(path)+1); + + strcpy(retval,path); + + return(retval); + +} /* __PHYSFS_platformRealPath */ + + +int __PHYSFS_platformMkDir(const char *path) +{ + wchar_t *w_path = AscToUnicode(path); + if(w_path!=NULL) + { + DWORD rc = CreateDirectory(w_path, NULL); + free(w_path); + if(rc==0) + { + return(0); + } + return(1); + } + else + { + return(0); + } +} /* __PHYSFS_platformMkDir */ + + +static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly) +{ + HANDLE fileHandle; + winCEfile *retval; + wchar_t *w_fname=AscToUnicode(fname); + + fileHandle = CreateFile(w_fname, mode, FILE_SHARE_READ, NULL, + creation, FILE_ATTRIBUTE_NORMAL, NULL); + + free(w_fname); + + if(fileHandle==INVALID_HANDLE_VALUE) + { + return NULL; + } + + BAIL_IF_MACRO(fileHandle == INVALID_HANDLE_VALUE, win32strerror(), NULL); + + retval = malloc(sizeof (winCEfile)); + if (retval == NULL) + { + CloseHandle(fileHandle); + BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); + } /* if */ + + retval->readonly = rdonly; + retval->handle = fileHandle; + return(retval); +} /* doOpen */ + + +void *__PHYSFS_platformOpenRead(const char *filename) +{ + return(doOpen(filename, GENERIC_READ, OPEN_EXISTING, 1)); +} /* __PHYSFS_platformOpenRead */ + + +void *__PHYSFS_platformOpenWrite(const char *filename) +{ + return(doOpen(filename, GENERIC_WRITE, CREATE_ALWAYS, 0)); +} /* __PHYSFS_platformOpenWrite */ + + +void *__PHYSFS_platformOpenAppend(const char *filename) +{ + void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0); + if (retval != NULL) + { + HANDLE h = ((winCEfile *) retval)->handle; + if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) + { + const char *err = win32strerror(); + CloseHandle(h); + free(retval); + BAIL_MACRO(err, NULL); + } /* if */ + } /* if */ + + return(retval); + +} /* __PHYSFS_platformOpenAppend */ + + +PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer, + PHYSFS_uint32 size, PHYSFS_uint32 count) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + DWORD CountOfBytesRead; + PHYSFS_sint64 retval; + + /* Read data from the file */ + /*!!! - uint32 might be a greater # than DWORD */ + if(!ReadFile(FileHandle, buffer, count * size, &CountOfBytesRead, NULL)) + { + retval=-1; + } /* if */ + else + { + /* Return the number of "objects" read. */ + /* !!! - What if not the right amount of bytes was read to make an object? */ + retval = CountOfBytesRead / size; + } /* else */ + + return(retval); + +} /* __PHYSFS_platformRead */ + + +PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer, + PHYSFS_uint32 size, PHYSFS_uint32 count) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + DWORD CountOfBytesWritten; + PHYSFS_sint64 retval; + + /* Read data from the file */ + /*!!! - uint32 might be a greater # than DWORD */ + if(!WriteFile(FileHandle, buffer, count * size, &CountOfBytesWritten, NULL)) + { + retval=-1; + } /* if */ + else + { + /* Return the number of "objects" read. */ + /*!!! - What if not the right number of bytes was written? */ + retval = CountOfBytesWritten / size; + } /* else */ + + return(retval); + +} /* __PHYSFS_platformWrite */ + + +int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + DWORD HighOrderPos; + DWORD rc; + + /* Get the high order 32-bits of the position */ + //HighOrderPos = HIGHORDER_UINT64(pos); + HighOrderPos = (unsigned long)(pos>>32); + + /*!!! SetFilePointer needs a signed 64-bit value. */ + /* Move pointer "pos" count from start of file */ + rc = SetFilePointer(FileHandle, (unsigned long)(pos&0x00000000ffffffff), + &HighOrderPos, FILE_BEGIN); + + if ((rc == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR)) + { + BAIL_MACRO(win32strerror(), 0); + } + + return(1); /* No error occured */ +} /* __PHYSFS_platformSeek */ + + +PHYSFS_sint64 __PHYSFS_platformTell(void *opaque) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + DWORD HighPos = 0; + DWORD LowPos; + PHYSFS_sint64 retval; + + /* Get current position */ + LowPos = SetFilePointer(FileHandle, 0, &HighPos, FILE_CURRENT); + if ((LowPos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR)) + { + BAIL_MACRO(win32strerror(), 0); + } /* 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 */ + + +PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + DWORD SizeHigh; + DWORD SizeLow; + PHYSFS_sint64 retval; + + SizeLow = GetFileSize(FileHandle, &SizeHigh); + if ((SizeLow == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR)) + { + BAIL_MACRO(win32strerror(), -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 */ + + +int __PHYSFS_platformEOF(void *opaque) +{ + PHYSFS_sint64 FilePosition; + int retval = 0; + + /* Get the current position in the file */ + if ((FilePosition = __PHYSFS_platformTell(opaque)) != 0) + { + /* Non-zero if EOF is equal to the file length */ + retval = FilePosition == __PHYSFS_platformFileLength(opaque); + } /* if */ + + return(retval); +} /* __PHYSFS_platformEOF */ + + +int __PHYSFS_platformFlush(void *opaque) +{ + winCEfile *fh = ((winCEfile *) opaque); + if (!fh->readonly) + BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), win32strerror(), 0); + + return(1); +} /* __PHYSFS_platformFlush */ + + +int __PHYSFS_platformClose(void *opaque) +{ + HANDLE FileHandle = ((winCEfile *) opaque)->handle; + BAIL_IF_MACRO(!CloseHandle(FileHandle), win32strerror(), 0); + free(opaque); + return(1); +} /* __PHYSFS_platformClose */ + + +int __PHYSFS_platformDelete(const char *path) +{ + wchar_t *w_path=AscToUnicode(path); + + /* If filename is a folder */ + if (GetFileAttributes(w_path) == FILE_ATTRIBUTE_DIRECTORY) + { + int retval=!RemoveDirectory(w_path); + free(w_path); + BAIL_IF_MACRO(retval, win32strerror(), 0); + } /* if */ + else + { + int retval=!DeleteFile(w_path); + free(w_path); + BAIL_IF_MACRO(retval, win32strerror(), 0); + } /* else */ + + return(1); /* if you got here, it worked. */ +} /* __PHYSFS_platformDelete */ + + +void *__PHYSFS_platformCreateMutex(void) +{ + return((void *) CreateMutex(NULL, FALSE, NULL)); +} /* __PHYSFS_platformCreateMutex */ + + +void __PHYSFS_platformDestroyMutex(void *mutex) +{ + CloseHandle((HANDLE) mutex); +} /* __PHYSFS_platformDestroyMutex */ + + +int __PHYSFS_platformGrabMutex(void *mutex) +{ + return(WaitForSingleObject((HANDLE) mutex, INFINITE) != WAIT_FAILED); +} /* __PHYSFS_platformGrabMutex */ + + +void __PHYSFS_platformReleaseMutex(void *mutex) +{ + ReleaseMutex((HANDLE) mutex); +} /* __PHYSFS_platformReleaseMutex */ + + +PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname) +{ + BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1); +} /* __PHYSFS_platformGetLastModTime */ + +/* end of skeleton.c ... */ +