#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) retVal = 1; else if (((mode & O_RDWR) || (mode & O_WRONLY)) && (attribs & FILE_ATTRIBUTE_READONLY)) retVal = 1; 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; } // TODO: create a directory int mkdir(const char *) { ASSERT(0); return 0; } // TODO: delete a file int remove(const char *) { ASSERT(0); return 0; } const char* adaptpath(const char *path) { static SWBuf retVal; retVal = ""; if ((*path != '/') && (*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; } retVal += "/"; SWBuf tmp = path; while ((tmp[0] == '/') || (tmp[0] == '\\') || (tmp[0] == '.')) tmp << 1; retVal += tmp; for (int pos = 0; retVal[pos]; pos++) { switch (retVal[pos]) { case '/': retVal[pos] = '\\'; break; } } return retVal.c_str(); }