win_efile.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 1,417 行 · 第 1/3 页
C
1,417 行
} /* * Some new error has occurred. Don't know what it * could be, but report this one. */ errno = errno_map(GetLastError()); CreateDirectory(dst, NULL); SetFileAttributes(dst, dstAttr); if (errno == EACCES) { /* * Decode the EACCES to a more meaningful error. */ goto decode; } } } else { /* (dstAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */ errno = ENOTDIR; } } else { /* (srcAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */ if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) { errno = EISDIR; } else { /* * Overwrite existing file by: * * 1. Rename existing file to temp name. * 2. Rename old file to new name. * 3. If success, delete temp file. If failure, * put temp file back to old name. */ char tempName[MAX_PATH]; int result, size; char *rest; size = GetFullPathName(dst, sizeof(tempName), tempName, &rest); if ((size == 0) || (size > sizeof(tempName)) || (rest == NULL)) { return check_error(-1, errInfo); } *rest = '\0'; result = -1; if (GetTempFileName(tempName, "erlr", 0, tempName) != 0) { /* * Strictly speaking, need the following DeleteFile and * MoveFile to be joined as an atomic operation so no * other app comes along in the meantime and creates the * same temp file. */ DeleteFile(tempName); if (MoveFile(dst, tempName) != FALSE) { if (MoveFile(src, dst) != FALSE) { SetFileAttributes(tempName, FILE_ATTRIBUTE_NORMAL); DeleteFile(tempName); return 1; } else { DeleteFile(dst); MoveFile(tempName, dst); } } /* * Can't backup dst file or move src file. Return that * error. Could happen if an open file refers to dst. */ errno = errno_map(GetLastError()); if (errno == EACCES) { /* * Decode the EACCES to a more meaningful error. */ goto decode; } } return result; } } } return check_error(-1, errInfo);}intefile_chdir(errInfo, name)Efile_error* errInfo; /* Where to return error codes. */char* name; /* Name of directory to make current. */{ int success = check_error(chdir(name), errInfo); if (!success && errInfo->posix_errno == EINVAL) /* POSIXification of errno */ errInfo->posix_errno = ENOENT; return success;}intefile_getdcwd(errInfo, drive, buffer, size)Efile_error* errInfo; /* Where to return error codes. */int drive; /* 0 - current, 1 - A, 2 - B etc. */char* buffer; /* Where to return the current directory. */size_t size; /* Size of buffer. */{ if (_getdcwd(drive, buffer, size) == NULL) return check_error(-1, errInfo); for ( ; *buffer; buffer++) if (*buffer == '\\') *buffer = '/'; return 1;}intefile_readdir(errInfo, name, dir_handle, buffer, size)Efile_error* errInfo; /* Where to return error codes. */char* name; /* Name of directory to open. */EFILE_DIR_HANDLE* dir_handle; /* Directory handle of open directory. */char* buffer; /* Pointer to buffer for one filename. */size_t size; /* Size of buffer. */{ HANDLE dir; /* Handle to directory. */ char wildcard[MAX_PATH]; /* Wildcard to search for. */ WIN32_FIND_DATA findData; /* Data found by FindFirstFile() or FindNext(). */ /* * First time we must setup everything. */ if (*dir_handle == NULL) { int length = strlen(name); char* s; if (length+3 >= MAX_PATH) { errno = ENAMETOOLONG; return check_error(-1, errInfo); } strcpy(wildcard, name); s = wildcard+length-1; if (*s != '/' && *s != '\\') *++s = '\\'; *++s = '*'; *++s = '\0'; DEBUGF(("Reading %s\n", wildcard)); dir = FindFirstFile(wildcard, &findData); if (dir == INVALID_HANDLE_VALUE) return set_error(errInfo); *dir_handle = (EFILE_DIR_HANDLE) dir; if (!IS_DOT_OR_DOTDOT(findData.cFileName)) { strcpy(buffer, findData.cFileName); return 1; } } /* * Retrieve the name of the next file using the directory handle. */ dir = (HANDLE) *dir_handle; for (;;) { if (FindNextFile(dir, &findData)) { if (IS_DOT_OR_DOTDOT(findData.cFileName)) continue; strcpy(buffer, findData.cFileName); return 1; } if (GetLastError() == ERROR_NO_MORE_FILES) { FindClose(dir); errInfo->posix_errno = errInfo->os_errno = 0; return 0; } set_error(errInfo); FindClose(dir); return 0; }}intefile_openfile(errInfo, name, flags, pfd, pSize)Efile_error* errInfo; /* Where to return error codes. */char* name; /* Name of directory to open. */int flags; /* Flags to use for opening. */int* pfd; /* Where to store the file descriptor. */off_t* pSize; /* Where to store the size of the file. */{ BY_HANDLE_FILE_INFORMATION fileInfo; /* File information from a handle. */ HANDLE fd; /* Handle to open file. */ DWORD access; /* Access mode: GENERIC_READ, GENERIC_WRITE. */ DWORD crFlags; switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) { case EFILE_MODE_READ: access = GENERIC_READ; crFlags = OPEN_EXISTING; break; case EFILE_MODE_WRITE: access = GENERIC_WRITE; crFlags = CREATE_ALWAYS; break; case EFILE_MODE_READ_WRITE: access = GENERIC_READ|GENERIC_WRITE; crFlags = OPEN_ALWAYS; break; default: errno = EINVAL; check_error(-1, errInfo); return 0; } if (flags & EFILE_MODE_APPEND) { crFlags = OPEN_ALWAYS; } fd = CreateFile(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL); /* * Check for errors. */ if (fd == INVALID_HANDLE_VALUE) { DWORD attr; set_error(errInfo); /* * If the error is EACESS, the reason could be that we tried to * open a directory. In that case, we'll change the error code * to EISDIR. */ if (errInfo->posix_errno && (attr = GetFileAttributes(name)) != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { errInfo->posix_errno = EISDIR; } return 0; } /* * Get and return the length of the open file. */ if (!GetFileInformationByHandle(fd, &fileInfo)) return set_error(errInfo); *pfd = (int) fd; *pSize = fileInfo.nFileSizeLow; return 1;}int efile_may_openfile(Efile_error* errInfo, char *name) { DWORD attr; if ((attr = GetFileAttributes(name)) == INVALID_FILE_ATTRIBUTES) { return check_error(-1, errInfo); } if (attr & FILE_ATTRIBUTE_DIRECTORY) { errno = EISDIR; return check_error(-1, errInfo); } return 1;#if 0 struct stat statbuf; if (stat(name, &statbuf)) { return check_error(-1, errInfo); } if (ISDIR(statbuf)) { errno = EISDIR; return check_error(-1, errInfo); } return 1;#endif}voidefile_closefile(fd)int fd; /* File descriptor for file to close. */{ CloseHandle((HANDLE) fd);}intefile_fsync(errInfo, fd)Efile_error* errInfo; /* Where to return error codes. */int fd; /* File descriptor for file to sync. */{ if (!FlushFileBuffers((HANDLE) fd)) { return check_error(-1, errInfo); } return 1;}intefile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, char* orig_name, int info_for_link){ HANDLE findhandle; /* Handle returned by FindFirstFile(). */ WIN32_FIND_DATA findbuf; /* Data return by FindFirstFile(). */ 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. */ errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; return 0; } else drive = tolower(*name) - 'a' + 1; findhandle = FindFirstFile(name, &findbuf); if (findhandle == 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) ) ) { errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; return 0; } /* * Root directories (such as C:\ or \\server\share\ are fabricated. */ findbuf.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; findbuf.nFileSizeHigh = 0; findbuf.nFileSizeLow = 0; findbuf.cFileName[0] = '\0'; pInfo->modifyTime.year = 1980; pInfo->modifyTime.month = 1; pInfo->modifyTime.day = 1; pInfo->modifyTime.hour = 0; pInfo->modifyTime.minute = 0; pInfo->modifyTime.second = 0; pInfo->accessTime = pInfo->modifyTime; } else { SYSTEMTIME SystemTime; FILETIME LocalFTime;#define GET_TIME(dst, src) \if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \ !FileTimeToSystemTime(&LocalFTime, &SystemTime)) { \ return set_error(errInfo); \} \(dst).year = SystemTime.wYear; \(dst).month = SystemTime.wMonth; \(dst).day = SystemTime.wDay; \(dst).hour = SystemTime.wHour; \(dst).minute = SystemTime.wMinute; \(dst).second = SystemTime.wSecond; GET_TIME(pInfo->modifyTime, ftLastWriteTime); if (findbuf.ftLastAccessTime.dwLowDateTime == 0 && findbuf.ftLastAccessTime.dwHighDateTime == 0) { pInfo->accessTime = pInfo->modifyTime; } else { GET_TIME(pInfo->accessTime, ftLastAccessTime); } if (findbuf.ftCreationTime.dwLowDateTime == 0 && findbuf.ftCreationTime.dwHighDateTime == 0) { pInfo->cTime = pInfo->modifyTime; } else { GET_TIME(pInfo->cTime, ftCreationTime); }#undef GET_TIME FindClose(findhandle); } pInfo->size_low = findbuf.nFileSizeLow; pInfo->size_high = findbuf.nFileSizeHigh; if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) pInfo->type = FT_DIRECTORY; else pInfo->type = FT_REGULAR; if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) pInfo->access = FA_READ; else pInfo->access = FA_READ|FA_WRITE; pInfo->mode = dos_to_posix_mode(findbuf.dwFileAttributes, name); pInfo->links = 1; pInfo->major_device = drive; pInfo->minor_device = 0; pInfo->inode = 0; pInfo->uid = 0; pInfo->gid = 0; return 1;}intefile_write_info(errInfo, pInfo, name)Efile_error* errInfo;Efile_info* pInfo;char* name;{ SYSTEMTIME timebuf; FILETIME LocalFileTime; FILETIME ModifyFileTime; FILETIME AccessFileTime; FILETIME CreationFileTime; HANDLE fd; FILETIME* mtime = NULL; FILETIME* atime = NULL; FILETIME* ctime = NULL; DWORD attr; DWORD tempAttr; BOOL modifyTime = FALSE; /* * Get the attributes for the file. */ tempAttr = attr = GetFileAttributes((LPTSTR)name); if (attr == 0xffffffff) { return set_error(errInfo); } if (pInfo->mode != -1) { if (pInfo->mode & _S_IWRITE) { /* clear read only bit */ attr &= ~FILE_ATTRIBUTE_READONLY; } else { /* set read only bit */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?