📄 w95io.c
字号:
if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d)) continue; return fileName; } err = GetLastError(); PR_ASSERT(NO_ERROR != err); _PR_MD_MAP_READDIR_ERROR(err); return NULL; } PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return NULL;}PRInt32_PR_MD_DELETE(const char *name){ if (DeleteFile(name)) { return 0; } else { _PR_MD_MAP_DELETE_ERROR(GetLastError()); return -1; }}static void_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm){ PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime)); CopyMemory(prtm, filetime, sizeof(PRTime));#if defined(__MINGW32__) *prtm = (*prtm - _pr_filetime_offset) / 10LL;#else *prtm = (*prtm - _pr_filetime_offset) / 10i64;#endif#ifdef DEBUG /* Doublecheck our calculation. */ { SYSTEMTIME systime; PRExplodedTime etm; PRTime cmp; /* for comparison */ BOOL rv; rv = FileTimeToSystemTime(filetime, &systime); PR_ASSERT(0 != rv); /* * PR_ImplodeTime ignores wday and yday. */ etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC; etm.tm_sec = systime.wSecond; etm.tm_min = systime.wMinute; etm.tm_hour = systime.wHour; etm.tm_mday = systime.wDay; etm.tm_month = systime.wMonth - 1; etm.tm_year = systime.wYear; /* * It is not well-documented what time zone the FILETIME's * are in. WIN32_FIND_DATA is documented to be in UTC (GMT). * But BY_HANDLE_FILE_INFORMATION is unclear about this. * By our best judgement, we assume that FILETIME is in UTC. */ etm.tm_params.tp_gmt_offset = 0; etm.tm_params.tp_dst_offset = 0; cmp = PR_ImplodeTime(&etm); /* * SYSTEMTIME is in milliseconds precision, so we convert PRTime's * microseconds to milliseconds before doing the comparison. */ PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC)); }#endif /* DEBUG */}PRInt32_PR_MD_STAT(const char *fn, struct stat *info){ PRInt32 rv; rv = _stat(fn, (struct _stat *)info); if (-1 == rv) { /* * Check for MSVC runtime library _stat() bug. * (It's really a bug in FindFirstFile().) * If a pathname ends in a backslash or slash, * e.g., c:\temp\ or c:/temp/, _stat() will fail. * Note: a pathname ending in a slash (e.g., c:/temp/) * can be handled by _stat() on NT but not on Win95. * * We remove the backslash or slash at the end and * try again. */ int len = strlen(fn); if (len > 0 && len <= _MAX_PATH && (fn[len - 1] == '\\' || fn[len - 1] == '/')) { char newfn[_MAX_PATH + 1]; strcpy(newfn, fn); newfn[len - 1] = '\0'; rv = _stat(newfn, (struct _stat *)info); } } if (-1 == rv) { _PR_MD_MAP_STAT_ERROR(errno); } return rv;}#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')/* * IsRootDirectory -- * * Return PR_TRUE if the pathname 'fn' is a valid root directory, * else return PR_FALSE. The char buffer pointed to by 'fn' must * be writable. During the execution of this function, the contents * of the buffer pointed to by 'fn' may be modified, but on return * the original contents will be restored. 'buflen' is the size of * the buffer pointed to by 'fn'. * * Root directories come in three formats: * 1. / or \, meaning the root directory of the current drive. * 2. C:/ or C:\, where C is a drive letter. * 3. \\<server name>\<share point name>\ or * \\<server name>\<share point name>, meaning the root directory * of a UNC (Universal Naming Convention) name. */static PRBoolIsRootDirectory(char *fn, size_t buflen){ char *p; PRBool slashAdded = PR_FALSE; PRBool rv = PR_FALSE; if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { return PR_TRUE; } if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) && fn[3] == '\0') { rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; return rv; } /* The UNC root directory */ if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { /* The 'server' part should have at least one character. */ p = &fn[2]; if (*p == '\0' || _PR_IS_SLASH(*p)) { return PR_FALSE; } /* look for the next slash */ do { p++; } while (*p != '\0' && !_PR_IS_SLASH(*p)); if (*p == '\0') { return PR_FALSE; } /* The 'share' part should have at least one character. */ p++; if (*p == '\0' || _PR_IS_SLASH(*p)) { return PR_FALSE; } /* look for the final slash */ do { p++; } while (*p != '\0' && !_PR_IS_SLASH(*p)); if (_PR_IS_SLASH(*p) && p[1] != '\0') { return PR_FALSE; } if (*p == '\0') { /* * GetDriveType() doesn't work correctly if the * path is of the form \\server\share, so we add * a final slash temporarily. */ if ((p + 1) < (fn + buflen)) { *p++ = '\\'; *p = '\0'; slashAdded = PR_TRUE; } else { return PR_FALSE; /* name too long */ } } rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; /* restore the 'fn' buffer */ if (slashAdded) { *--p = '\0'; } } return rv;}PRInt32_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info){ HANDLE hFindFile; WIN32_FIND_DATA findFileData; char pathbuf[MAX_PATH + 1]; if (NULL == fn || '\0' == *fn) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return -1; } /* * FindFirstFile() expands wildcard characters. So * we make sure the pathname contains no wildcard. */ if (NULL != _mbspbrk(fn, "?*")) { PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0); return -1; } hFindFile = FindFirstFile(fn, &findFileData); if (INVALID_HANDLE_VALUE == hFindFile) { DWORD len; char *filePart; /* * FindFirstFile() does not work correctly on root directories. * It also doesn't work correctly on a pathname that ends in a * slash. So we first check to see if the pathname specifies a * root directory. If not, and if the pathname ends in a slash, * we remove the final slash and try again. */ /* * If the pathname does not contain ., \, and /, it cannot be * a root directory or a pathname that ends in a slash. */ if (NULL == _mbspbrk(fn, ".\\/")) { _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); return -1; } len = GetFullPathName(fn, sizeof(pathbuf), pathbuf, &filePart); if (0 == len) { _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); return -1; } if (len > sizeof(pathbuf)) { PR_SetError(PR_NAME_TOO_LONG_ERROR, 0); return -1; } if (IsRootDirectory(pathbuf, sizeof(pathbuf))) { info->type = PR_FILE_DIRECTORY; info->size = 0; /* * These timestamps don't make sense for root directories. */ info->modifyTime = 0; info->creationTime = 0; return 0; } if (!_PR_IS_SLASH(pathbuf[len - 1])) { _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); return -1; } else { pathbuf[len - 1] = '\0'; hFindFile = FindFirstFile(pathbuf, &findFileData); if (INVALID_HANDLE_VALUE == hFindFile) { _PR_MD_MAP_OPENDIR_ERROR(GetLastError()); return -1; } } } FindClose(hFindFile); if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { info->type = PR_FILE_DIRECTORY; } else { info->type = PR_FILE_FILE; } info->size = findFileData.nFileSizeHigh; info->size = (info->size << 32) + findFileData.nFileSizeLow; _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime); if (0 == findFileData.ftCreationTime.dwLowDateTime && 0 == findFileData.ftCreationTime.dwHighDateTime) { info->creationTime = info->modifyTime; } else { _PR_FileTimeToPRTime(&findFileData.ftCreationTime, &info->creationTime); } return 0;}PRInt32_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info){ PRFileInfo64 info64; PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64); if (0 == rv) { info->type = info64.type; info->size = (PRUint32) info64.size; info->modifyTime = info64.modifyTime; info->creationTime = info64.creationTime; } return rv;}PRInt32_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info){ int rv; BY_HANDLE_FILE_INFORMATION hinfo; rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo); if (rv == FALSE) { _PR_MD_MAP_FSTAT_ERROR(GetLastError()); return -1; } if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) info->type = PR_FILE_DIRECTORY; else info->type = PR_FILE_FILE; info->size = hinfo.nFileSizeHigh; info->size = (info->size << 32) + hinfo.nFileSizeLow; _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) ); _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) ); return 0;}PRInt32_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info){ PRFileInfo64 info64; int rv = _PR_MD_GETOPENFILEINFO64(fd, &info64); if (0 == rv) { info->type = info64.type; info->modifyTime = info64.modifyTime; info->creationTime = info64.creationTime; LL_L2I(info->size, info64.size); } return rv;}PRStatus_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable){ BOOL rv; /* * The SetHandleInformation function fails with the * ERROR_CALL_NOT_IMPLEMENTED error on Win95. */ rv = SetHandleInformation( (HANDLE)fd->secret->md.osfd, HANDLE_FLAG_INHERIT, inheritable ? HANDLE_FLAG_INHERIT : 0); if (0 == rv) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); return PR_FAILURE; } return PR_SUCCESS;} void_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported){ if (imported) { fd->secret->inheritable = _PR_TRI_UNKNOWN; } else { fd->secret->inheritable = _PR_TRI_FALSE; }}void_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd){ DWORD flags; PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable); if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) { if (flags & HANDLE_FLAG_INHERIT) { fd->secret->inheritable = _PR_TRI_TRUE; } else { fd->secret->inheritable = _PR_TRI_FALSE; } }}PRInt32_PR_MD_RENAME(const char *from, const char *to){ /* Does this work with dot-relative pathnames? */ if (MoveFile(from, to)) { return 0; } else { _PR_MD_MAP_RENAME_ERROR(GetLastError()); return -1; }}PRInt32_PR_MD_ACCESS(const char *name, PRAccessHow how){PRInt32 rv; switch (how) { case PR_ACCESS_WRITE_OK: rv = _access(name, 02); break; case PR_ACCESS_READ_OK: rv = _access(name, 04); break; case PR_ACCESS_EXISTS: return _access(name, 00); break; default: PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return -1; } if (rv < 0) _PR_MD_MAP_ACCESS_ERROR(errno); return rv;}PRInt32_PR_MD_MKDIR(const char *name, PRIntn mode){ /* XXXMB - how to translate the "mode"??? */ if (CreateDirectory(name, NULL)) { return 0; } else { _PR_MD_MAP_MKDIR_ERROR(GetLastError()); return -1; }}PRInt32_PR_MD_MAKE_DIR(const char *name, PRIntn mode){ BOOL rv; SECURITY_ATTRIBUTES sa; LPSECURITY_ATTRIBUTES lpSA = NULL; PSECURITY_DESCRIPTOR pSD = NULL; PACL pACL = NULL; if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable, &pSD, &pACL) == PR_SUCCESS) { sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; lpSA = &sa; } rv = CreateDirectory(name, lpSA); if (lpSA != NULL) { _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); } if (rv) { return 0; } else { _PR_MD_MAP_MKDIR_ERROR(GetLastError()); return -1; }}PRInt32_PR_MD_RMDIR(const char *name){ if (RemoveDirectory(name)) { return 0; } else { _PR_MD_MAP_RMDIR_ERROR(GetLastError()); return -1; }}PRStatus_PR_MD_LOCKFILE(PRInt32 f){ PRStatus rc = PR_SUCCESS; DWORD rv; rv = LockFile( (HANDLE)f, 0l, 0l, 0x0l, 0xffffffffl ); if ( rv == 0 ) { DWORD rc = GetLastError(); PR_LOG( _pr_io_lm, PR_LOG_ERROR, ("_PR_MD_LOCKFILE() failed. Error: %d", rc )); rc = PR_FAILURE; } return rc;} /* end _PR_MD_LOCKFILE() */PRStatus_PR_MD_TLOCKFILE(PRInt32 f){ PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); return PR_FAILURE;} /* end _PR_MD_TLOCKFILE() */PRStatus_PR_MD_UNLOCKFILE(PRInt32 f){ PRInt32 rv; rv = UnlockFile( (HANDLE) f, 0l, 0l, 0x0l, 0xffffffffl ); if ( rv ) { return PR_SUCCESS; } else { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); return PR_FAILURE; }} /* end _PR_MD_UNLOCKFILE() */PRInt32_PR_MD_PIPEAVAILABLE(PRFileDesc *fd){ if (NULL == fd) PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); else PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -