📄 filestat.c
字号:
((wanted & APR_FINFO_PROT) ? &dacl : NULL), NULL, &pdesc); if (rv == ERROR_SUCCESS) apr_pool_cleanup_register(finfo->cntxt, pdesc, free_localheap, apr_pool_cleanup_null); else user = grp = dacl = NULL; if (user) { finfo->user = user; finfo->valid |= APR_FINFO_USER; } if (grp) { finfo->group = grp; finfo->valid |= APR_FINFO_GROUP; } if (dacl) { /* Retrieved the discresionary access list */ resolve_prot(finfo, wanted, dacl); } } return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);}/* This generic fillin depends upon byhandle to be passed as 0 when * a WIN32_FILE_ATTRIBUTE_DATA or either WIN32_FIND_DATA [A or W] is * passed for wininfo. When the BY_HANDLE_FILE_INFORMATION structure * is passed for wininfo, byhandle is passed as 1 to offset the one * dword discrepancy in the High/Low size structure members. */void fillin_fileinfo(apr_finfo_t *finfo, WIN32_FILE_ATTRIBUTE_DATA *wininfo, int byhandle) { DWORD *sizes = &wininfo->nFileSizeHigh + byhandle; memset(finfo, '\0', sizeof(*finfo)); FileTimeToAprTime(&finfo->atime, &wininfo->ftLastAccessTime); FileTimeToAprTime(&finfo->ctime, &wininfo->ftCreationTime); FileTimeToAprTime(&finfo->mtime, &wininfo->ftLastWriteTime);#if APR_HAS_LARGE_FILES finfo->size = (apr_off_t)sizes[1] | ((apr_off_t)sizes[0] << 32);#else finfo->size = (apr_off_t)sizes[1]; if (finfo->size < 0 || sizes[0]) finfo->size = 0x7fffffff;#endif if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { finfo->filetype = APR_LNK; } else if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { finfo->filetype = APR_DIR; } else { /* XXX: Solve this: Short of opening the handle to the file, the * 'FileType' appears to be unknowable (in any trustworthy or * consistent sense), that is, as far as PIPE, CHR, etc are concerned. */ finfo->filetype = APR_REG; } /* The following flags are [for this moment] private to Win32. * That's the only excuse for not toggling valid bits to reflect them. */ if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_READONLY) finfo->protection = APR_FREADONLY; finfo->valid = APR_FINFO_ATIME | APR_FINFO_CTIME | APR_FINFO_MTIME | APR_FINFO_SIZE | APR_FINFO_TYPE; /* == APR_FINFO_MIN */}APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted, apr_file_t *thefile){ BY_HANDLE_FILE_INFORMATION FileInfo; if (!GetFileInformationByHandle(thefile->filehand, &FileInfo)) { return apr_get_os_error(); } fillin_fileinfo(finfo, (WIN32_FILE_ATTRIBUTE_DATA *) &FileInfo, 1); finfo->cntxt = thefile->cntxt; /* Extra goodies known only by GetFileInformationByHandle() */ finfo->inode = (apr_ino_t)FileInfo.nFileIndexLow | ((apr_ino_t)FileInfo.nFileIndexHigh << 32); finfo->device = FileInfo.dwVolumeSerialNumber; finfo->nlink = FileInfo.nNumberOfLinks; finfo->valid |= APR_FINFO_IDENT | APR_FINFO_NLINK; if ((wanted & APR_FINFO_TYPE) && (APR_FINFO_TYPE == APR_REG)) { /* Go the extra mile to be -certain- that we have a real, regular * file, since the attribute bits aren't a certain thing. */ DWORD FileType; if (FileType = GetFileType(thefile->filehand)) { if (FileType == FILE_TYPE_DISK) { finfo->filetype = APR_REG; } else if (FileType == FILE_TYPE_CHAR) { finfo->filetype = APR_CHR; } else if (FileType == FILE_TYPE_PIPE) { finfo->filetype = APR_PIPE; } else { finfo->filetype = APR_NOFILE; } } } if (wanted &= ~finfo->valid) { apr_oslevel_e os_level; if (apr_get_oslevel(thefile->cntxt, &os_level)) os_level = APR_WIN_95; return more_finfo(finfo, thefile->filehand, wanted, MORE_OF_HANDLE, os_level); } return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname, apr_fileperms_t perms){ return APR_ENOTIMPL;}APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *cont){#ifdef APR_HAS_UNICODE_FS apr_wchar_t wfname[APR_PATH_MAX];#endif apr_oslevel_e os_level; char *filename = NULL; /* These all share a common subset of this structure */ union { WIN32_FIND_DATAW w; WIN32_FIND_DATAA n; WIN32_FILE_ATTRIBUTE_DATA i; } FileInfo; if (apr_get_oslevel(cont, &os_level)) os_level = APR_WIN_95; /* Catch fname length == MAX_PATH since GetFileAttributesEx fails * with PATH_NOT_FOUND. We would rather indicate length error than * 'not found' */ if (strlen(fname) >= APR_PATH_MAX) { return APR_ENAMETOOLONG; }#ifdef APR_HAS_UNICODE_FS if (os_level >= APR_WIN_NT) { apr_status_t rv; if (rv = utf8_to_unicode_path(wfname, sizeof(wfname) / sizeof(apr_wchar_t), fname)) return rv; if (!(wanted & APR_FINFO_NAME)) { if (!GetFileAttributesExW(wfname, GetFileExInfoStandard, &FileInfo.i)) return apr_get_os_error(); } else { /* Guard against bogus wildcards and retrieve by name * since we want the true name, and set aside a long * enough string to handle the longest file name. */ char tmpname[APR_FILE_MAX * 3 + 1]; HANDLE hFind; if (strchr(fname, '*') || strchr(fname, '?')) return APR_ENOENT; hFind = FindFirstFileW(wfname, &FileInfo.w); if (hFind == INVALID_HANDLE_VALUE) return apr_get_os_error(); FindClose(hFind); if (unicode_to_utf8_path(tmpname, sizeof(tmpname), FileInfo.w.cFileName)) { return APR_ENAMETOOLONG; } filename = apr_pstrdup(cont, tmpname); } } else #endif if ((os_level >= APR_WIN_98) && !(wanted & APR_FINFO_NAME)) { if (!GetFileAttributesExA(fname, GetFileExInfoStandard, &FileInfo.i)) { return apr_get_os_error(); } } else { /* Guard against bogus wildcards and retrieve by name * since we want the true name, or are stuck in Win95 */ HANDLE hFind; if (strchr(fname, '*') || strchr(fname, '?')) return APR_ENOENT; hFind = FindFirstFileA(fname, &FileInfo.n); if (hFind == INVALID_HANDLE_VALUE) { return apr_get_os_error(); } FindClose(hFind); filename = apr_pstrdup(cont, FileInfo.n.cFileName); } fillin_fileinfo(finfo, (WIN32_FILE_ATTRIBUTE_DATA *) &FileInfo, 0); finfo->cntxt = cont; if (filename) { finfo->name = filename; finfo->valid |= APR_FINFO_NAME; } if (wanted &= ~finfo->valid) { /* Caller wants more than APR_FINFO_MIN | APR_FINFO_NAME */#ifdef APR_HAS_UNICODE_FS if (os_level >= APR_WIN_NT) return more_finfo(finfo, wfname, wanted, MORE_OF_WFSPEC, os_level);#endif return more_finfo(finfo, fname, wanted, MORE_OF_FSPEC, os_level); } return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_lstat(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *cont){ return apr_stat(finfo, fname, wanted & APR_FINFO_LINK, cont);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -