win_efile.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 1,417 行 · 第 1/3 页
C
1,417 行
attr |= FILE_ATTRIBUTE_READONLY; } } /* * Construct all file times. */#define MKTIME(tb, ts, ptr) \ timebuf.wYear = ts.year; \ timebuf.wMonth = ts.month; \ timebuf.wDay = ts.day; \ timebuf.wHour = ts.hour; \ timebuf.wMinute = ts.minute; \ timebuf.wSecond = ts.second; \ timebuf.wMilliseconds = 0; \ if (ts.year != -1) { \ modifyTime = TRUE; \ ptr = &tb; \ if (!SystemTimeToFileTime(&timebuf, &LocalFileTime ) || \ !LocalFileTimeToFileTime(&LocalFileTime, &tb)) { \ errno = EINVAL; \ return check_error(-1, errInfo); \ } \ } MKTIME(ModifyFileTime, pInfo->accessTime, mtime); MKTIME(AccessFileTime, pInfo->modifyTime, atime); MKTIME(CreationFileTime, pInfo->cTime, ctime);#undef MKTIME /* * If necessary, set the file times. */ if (modifyTime) { /* * If the has read only access, we must temporarily turn on * write access (this is necessary for native filesystems, * but not for NFS filesystems). */ if (tempAttr & FILE_ATTRIBUTE_READONLY) { tempAttr &= ~FILE_ATTRIBUTE_READONLY; if (!SetFileAttributes((LPTSTR) name, tempAttr)) { return set_error(errInfo); } } fd = CreateFile(name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fd != INVALID_HANDLE_VALUE) { BOOL result = SetFileTime(fd, ctime, atime, mtime); if (!result) { return set_error(errInfo); } CloseHandle(fd); } } /* * If the file doesn't have the correct attributes, set them now. * (It could have been done before setting the file times, above). */ if (tempAttr != attr) { if (!SetFileAttributes((LPTSTR) name, attr)) { return set_error(errInfo); } } return 1;}intefile_pwrite(errInfo, fd, buf, count, offset)Efile_error* errInfo; /* Where to return error codes. */int fd; /* File descriptor to write to. */char* buf; /* Buffer to write. */size_t count; /* Number of bytes to write. */off_t offset; /* where to write it */{ int res, location; if ((res = efile_seek(errInfo, fd, offset, EFILE_SEEK_SET, &location))) return efile_write(errInfo, EFILE_MODE_WRITE, fd, buf, count); else return res;}/* position and read/write as a single atomic op */intefile_pread(errInfo, fd, offset, buf, count, pBytesRead)Efile_error* errInfo; /* Where to return error codes. */int fd; /* File descriptor to read from. */off_t offset; /* Offset in bytes from BOF. */char* buf; /* Buffer to read into. */size_t count; /* Number of bytes to read. */size_t* pBytesRead; /* Where to return number of bytes read. */{ int res, location; if ((res = efile_seek(errInfo, fd, offset, EFILE_SEEK_SET, &location))) return efile_read(errInfo, EFILE_MODE_READ, fd, buf, count, pBytesRead); else return res;}intefile_write(errInfo, flags, fd, buf, count)Efile_error* errInfo; /* Where to return error codes. */int flags; /* Flags given when file was opened. */int fd; /* File descriptor to write to. */char* buf; /* Buffer to write. */size_t count; /* Number of bytes to write. */{ DWORD written; /* Bytes written in last operation. */ if (flags & EFILE_MODE_APPEND) { (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END); } while (count > 0) { if (!WriteFile((HANDLE) fd, buf, count, &written, NULL)) return set_error(errInfo); buf += written; count -= written; } return 1;}intefile_writev(Efile_error* errInfo, /* Where to return error codes */ int flags, /* Flags given when file was * opened */ int fd, /* File descriptor to write to */ SysIOVec* iov, /* Vector of buffer structs. * The structs are unchanged * after the call */ int iovcnt, /* Number of structs in vector */ size_t size) /* Number of bytes to write */{ int cnt; /* Buffers so far written */ ASSERT(iovcnt >= 0); if (flags & EFILE_MODE_APPEND) { (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END); } for (cnt = 0; cnt < iovcnt; cnt++) { if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { /* Non-empty buffer */ int p; /* Position in buffer */ int w = iov[cnt].iov_len;/* Bytes written in this call */ for (p = 0; p < iov[cnt].iov_len; p += w) { if (!WriteFile((HANDLE) fd, iov[cnt].iov_base + p, iov[cnt].iov_len - p, &w, NULL)) return set_error(errInfo); } } } return 1;}intefile_read(errInfo, flags, fd, buf, count, pBytesRead)Efile_error* errInfo; /* Where to return error codes. */int flags; /* Flags given when file was opened. */int fd; /* File descriptor to read from. */char* buf; /* Buffer to read into. */size_t count; /* Number of bytes to read. */size_t* pBytesRead; /* Where to return number of bytes read. */{ if (!ReadFile((HANDLE) fd, buf, count, (DWORD *) pBytesRead, NULL)) return set_error(errInfo); return 1;}intefile_seek(errInfo, fd, offset, origin, new_location)Efile_error* errInfo; /* Where to return error codes. */int fd; /* File descriptor to do the seek on. */off_t offset; /* Offset in bytes from the given origin. */int origin; /* Origin of seek (SEEK_SET, SEEK_CUR, * SEEK_END). */off_t* new_location; /* Resulting new location in file. */{ DWORD result; switch (origin) { case EFILE_SEEK_SET: origin = FILE_BEGIN; break; case EFILE_SEEK_CUR: origin = FILE_CURRENT; break; case EFILE_SEEK_END: origin = FILE_END; break; default: errno = EINVAL; check_error(-1, errInfo); break; } result = SetFilePointer((HANDLE) fd, offset, NULL, origin); if (result == (DWORD) -1) return set_error(errInfo); DEBUGF(("efile_seek(offset=%d, origin+%d) -> %d\n", offset, origin, result)); *new_location = (unsigned) result; return 1;}intefile_truncate_file(errInfo, fd, flags)Efile_error* errInfo; /* Where to return error codes. */int *fd; /* File descriptor for file to truncate. */int flags;{ if (!SetEndOfFile((HANDLE) (*fd))) return set_error(errInfo); return 1;}/* * IsRootUNCName - returns TRUE if the argument is a UNC name specifying * a root share. That is, if it is of the form \\server\share\. * This routine will also return true if the argument is of the * form \\server\share (no trailing slash) but Win32 currently * does not like that form. * * Forward slashes ('/') may be used instead of backslashes ('\'). */static intIsRootUNCName(const char* path){ /* * If a root UNC name, path will start with 2 (but not 3) slashes */ if ((strlen(path) >= 5) /* minimum string is "//x/y" */ && ISSLASH(path[0]) && ISSLASH(path[1])) { const char * p = path + 2 ; /* * find the slash between the server name and share name */ while ( * ++ p ) if ( ISSLASH(*p) ) break ; if ( *p && p[1] ) { /* * is there a further slash? */ while ( * ++ p ) if ( ISSLASH(*p) ) break ; /* * just final slash (or no final slash) */ if ( !*p || !p[1]) return 1; } } return 0 ;}/* * Extracts the root part of an absolute filename (by modifying the string * pointed to by the name argument). The name can start * with either a driver letter (for example, C:\), or a UNC name * (for example, \\guinness\bjorn). * * If the name is invalid, the buffer will be modified to point to * an empty string. * * Returns: 1 if the name consists of just the root part, 0 if * the name was longer. */static intextract_root(char* name){ int len = strlen(name); if (isalpha(name[0]) && name[1] == ':' && ISSLASH(name[2])) { int c = name[3]; name[3] = '\0'; return c == '\0'; } else if (len < 5 || !ISSLASH(name[0]) || !ISSLASH(name[1])) { goto error; } else { /* Try to find the end of the UNC name. */ char* p; int c; /* * Find the slash between the server name and share name. */ for (p = name + 2; *p; p++) if (ISSLASH(*p)) break; if (*p == '\0') goto error; /* * Find the slash after the share name. */ for (p++; *p; p++) if (ISSLASH(*p)) break; c = *p; *p = '\0'; return c == '\0' || p[1] == '\0'; } error: *name = '\0'; return 1;}static unsigned shortdos_to_posix_mode(int attr, const char *name){ register unsigned short uxmode; unsigned dosmode; register const char *p; dosmode = attr & 0xff; if ((p = name)[1] == ':') p += 2; /* check to see if this is a directory - note we must make a special * check for the root, which DOS thinks is not a directory */ uxmode = (unsigned short) (((ISSLASH(*p) && !p[1]) || (dosmode & FILE_ATTRIBUTE_DIRECTORY) || *p == '\0') ? _S_IFDIR|_S_IEXEC : _S_IFREG); /* If attribute byte does not have read-only bit, it is read-write */ uxmode |= (dosmode & FILE_ATTRIBUTE_READONLY) ? _S_IREAD : (_S_IREAD|_S_IWRITE); /* see if file appears to be executable - check extension of name */ if (p = strrchr(name, '.')) { if (!stricmp(p, ".exe") || !stricmp(p, ".cmd") || !stricmp(p, ".bat") || !stricmp(p, ".com")) uxmode |= _S_IEXEC; } /* propagate user read/write/execute bits to group/other fields */ uxmode |= (uxmode & 0700) >> 3; uxmode |= (uxmode & 0700) >> 6; return uxmode;}intefile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size){ errno = ENOTSUP; return check_error(-1, errInfo);}intefile_altname(Efile_error* errInfo, char* orig_name, char* buffer, size_t size){ WIN32_FIND_DATA wfd; HANDLE fh; char name[_MAX_PATH]; int name_len; char* path; char pathbuf[_MAX_PATH]; int drive; /* Drive for filename (1 = A:, 2 = B: etc). */ /* Don't allow wildcards to be interpreted by system */ if (strpbrk(orig_name, "?*")) { enoent: errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; return 0; } /* * Move the name to a buffer and make sure to remove a trailing * slash, because it causes FindFirstFile() to fail on Win95. */ if ((name_len = strlen(orig_name)) >= _MAX_PATH) { goto enoent; } else { strcpy(name, orig_name); if (name_len > 2 && ISSLASH(name[name_len-1]) && name[name_len-2] != ':') { name[name_len-1] = '\0'; } } /* Try to get disk from name. If none, get current disk. */ if (name[1] != ':') { drive = 0; if (GetCurrentDirectory(sizeof(pathbuf), pathbuf) && pathbuf[1] == ':') { drive = tolower(pathbuf[0]) - 'a' + 1; } } else if (*name && name[2] == '\0') { /* * X: and nothing more is an error. */ goto enoent; } else { drive = tolower(*name) - 'a' + 1; } fh = FindFirstFile(name,&wfd); if (fh == INVALID_HANDLE_VALUE) { if (!(strpbrk(name, "./\\") && (path = _fullpath(pathbuf, name, _MAX_PATH)) && /* root dir. ('C:\') or UNC root dir. ('\\server\share\') */ ((strlen(path) == 3) || IsRootUNCName(path)) && (GetDriveType(path) > 1) ) ) { errno = errno_map(GetLastError()); return check_error(-1, errInfo); } /* * Root directories (such as C:\ or \\server\share\ are fabricated. */ strcpy(buffer,name); return 1; } strcpy(buffer,wfd.cAlternateFileName); if (!*buffer) { strcpy(buffer,wfd.cFileName); } return 1;}intefile_link(Efile_error* errInfo, char* old, char* new){ errno = ENOTSUP; return check_error(-1, errInfo);}intefile_symlink(Efile_error* errInfo, char* old, char* new){ errno = ENOTSUP; return check_error(-1, errInfo);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?