#include #include #include #include #include #include using sword::SWBuf; // TODO: make list of our own file handles to make this work // static list openFileHandles // static int nextFileHandle = 1 int close (int fd) { if (fd > 0) { CloseHandle(*(HANDLE *)fd); delete (HANDLE *)fd; fd = 0; } return fd; } int open ( const char * path , int mode ) { bool exists = false; const char * winPath = adaptpath(path); wchar_t wbuf[MAX_PATH]; DWORD access = 0; DWORD create = OPEN_EXISTING; DWORD share = FILE_SHARE_READ; if (mode & O_WRONLY) access |= GENERIC_WRITE; else access |= GENERIC_READ; if (mode & O_RDWR) access |= GENERIC_READ | GENERIC_WRITE; mbstowcs(wbuf, winPath, MAX_PATH); // Quick test to see if file exists, if it does not exist this call fails. HANDLE hEx = CreateFile(wbuf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hEx != INVALID_HANDLE_VALUE) { CloseHandle(hEx); exists = true; } else { exists = false; } if(!exists && mode & O_CREAT) create = OPEN_ALWAYS; if(exists && mode & O_TRUNC) create = TRUNCATE_EXISTING; HANDLE *result = new HANDLE; (*result) = CreateFile(wbuf, access, share, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); if (*result == INVALID_HANDLE_VALUE) { //WCHAR buf[100]; //mbstowcs(buf,"file: ",6); //mbstowcs(&buf[6],winPath,100); //wcscpy(&buf[wcslen(buf)],L" error: "); //DWORD errorNr=GetLastError(); //_itow(errorNr,&buf[wcslen(buf)],10); //MessageBox(0,buf,L"Unable to open:",MB_OK|MB_ICONERROR); delete result; result = (HANDLE *)-1; } if (((int)result > -1) && (mode & O_APPEND)) { SetFilePointer(*result, 0, 0, FILE_END); } return (int) result; } int open(const char *path, int access, unsigned mode) { return open(path, access | mode); } int read(int fd, void *buf, size_t count) { DWORD readCount; __try { ReadFile(*(HANDLE *)fd, buf, (DWORD)count, &readCount, NULL); } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return (int)readCount; } int write(int fd, const void *buf, size_t count) { DWORD writtenCount; WriteFile(*(HANDLE *)fd, buf, (DWORD)count, &writtenCount, NULL); return writtenCount; } off_t lseek(int fildes, off_t offset, int whence) { DWORD wWence = 0; switch (whence) { case SEEK_SET: wWence = FILE_BEGIN; break; case SEEK_CUR: wWence = FILE_CURRENT; break; case SEEK_END: wWence = FILE_END; break; } off_t retVal = SetFilePointer(*(HANDLE *)fildes, (LONG)offset, 0, wWence); if (retVal == 0xFFFFFFFF) retVal = -1; return retVal; } int access(const char* path, int mode) { int retVal = 0; TCHAR buf[MAX_PATH]; mbstowcs(buf, adaptpath(path), MAX_PATH); DWORD attribs = GetFileAttributes(buf); if (attribs == 0xFFFFFFFF) { int err = GetLastError(); switch (err) { case ERROR_PATH_NOT_FOUND: //sbMessage ("access : %s : ERROR_PATH_NOT_FOUND\n",path); return 1; default: //sbMessage ("access : %s : %i\n",path,err); return 1; } } else if (((mode & O_RDWR) || (mode & O_WRONLY)) && (attribs & FILE_ATTRIBUTE_READONLY)) { retVal = 1; } else if (attribs & FILE_ATTRIBUTE_DIRECTORY) { return 0; } return retVal; } int stat ( const char * path, struct stat * s ) { int retVal = 0; wchar_t buf[MAX_PATH]; mbstowcs(buf, adaptpath(path), MAX_PATH); DWORD attribs = GetFileAttributes(buf); if (attribs == 0xFFFFFFFF) { retVal = 1; } else { s->st_mode = attribs; } return retVal; } #ifdef __cplusplus extern "C" { #endif int mkdir ( const char * path ) { wchar_t wbuf[MAX_PATH]; mbstowcs(wbuf, adaptpath(path), MAX_PATH); return CreateDirectory(wbuf,NULL) ? 0 : 1; } int remove (const char * path) { const char * winPath = adaptpath(path); wchar_t wbuf[MAX_PATH]; mbstowcs(wbuf, winPath, MAX_PATH); return DeleteFile(wbuf); } // TODO: create a directory int _mkdir ( const char * dir) { return mkdir(dir); } // TODO: delete a file int _unlink (const char * file) { return remove(file); } void rewind(FILE * file) { lseek ( (int)file , 0 , SEEK_SET ); } FILE * _fdopen(int fd, const char * type) { return (FILE *)fd; } FILE * fopen_wce (const char * path, const char * mode) { int m = 0; if (!strcmp(mode,"rb")) m = O_RDONLY; else if (!strcmp(mode,"wb") || !strcmp(mode,"w")) m = O_WRONLY | O_CREAT | O_TRUNC; else sbAssert(true); int ret = open ( path , m ); if (ret == -1) { sbMessage ("Failed to open %s %s\n",path,mode); ret = NULL; } return (FILE *)ret; } size_t fread_wce (void * buf, size_t size, size_t count, FILE * fd) { return (size_t) read ((int)fd, buf, count*size); } size_t fwrite_wce (const void * buf, size_t size, size_t count, FILE * fd) { return (size_t) write ((int)fd, buf, count*size ); } int fclose_wce (FILE * fd) { return close ((int)fd); } int fseek_wce (FILE * fd, long offset, int whence) { return lseek ((int)fd, offset, whence); } #ifdef __cplusplus }; #endif const char* adaptpath ( const char * path ) { static SWBuf retVal; retVal = ""; //if (*path != '/' && *path != '\\' && !(path[1] == ':' && path[2] == '\\')) if (*path == '.') { static char buf [MAX_PATH] = "\\"; if (!strcmp(buf,"\\")) { TCHAR tbuf[MAX_PATH]; GetModuleFileName(NULL, tbuf, MAX_PATH); for (int i=_tcslen(tbuf); i>=0; i--) { if (tbuf[i]==L'\\') { wcstombs(buf, tbuf, i); break; } //ASSERT(i!=0); } } retVal = buf; } SWBuf tmp = path; //#ifndef WIN32 retVal += "/"; while ((tmp[0] == '/') || (tmp[0] == '\\') || (tmp[0] == '.')) tmp << 1; //#endif retVal += tmp; for (int pos = 0; retVal[pos]; pos++) { switch (retVal[pos]) { case '/': retVal[pos] = '\\'; break; } } return retVal.c_str(); }