struct cache_dir * _find_cache_dir(LPCSTR szPath, LPCSTR szPat) { struct cache_dir *cd; BOOL bFile; bFile = (_mbspbrk(szPath, "?*") == NULL); // // First match against the current non-cached dir // if ((cd = _dir_nocache) != NULL) { if (_match_dir(cd, bFile, szPath, szPat)) { return cd; } } // // Second search the dir cache list // for (cd = _dir_first; cd; cd = cd->cd_next) { if (_match_dir(cd, bFile, szPath, szPat)) { return cd; } } return NULL; }
static int do_play_sound (const char *psz_file, unsigned long ui_volume) { int i_result = 0; MCIERROR mci_error = 0; char sz_cmd_buf_a[520]; char sz_ret_buf_a[520]; MMRESULT mm_result = MMSYSERR_NOERROR; unsigned long ui_volume_org = 0; BOOL b_reset_volume = FALSE; char warn_text[560]; /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we need to encode the file in the ANSI codepage on Windows 9X even if w32_unicode_filenames is non-zero. */ if (w32_major_version <= 4 || !w32_unicode_filenames) { char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use; filename_to_ansi (psz_file, fname_a); fname_to_use = fname_a; /* If the file name is not encodable in ANSI, try its short 8+3 alias. This will only work if w32_unicode_filenames is non-zero. */ if (_mbspbrk ((const unsigned char *)fname_a, (const unsigned char *)"?")) { if (w32_get_short_filename (psz_file, shortname, MAX_PATH)) fname_to_use = shortname; else mci_error = MCIERR_FILE_NOT_FOUND; } if (!mci_error) { memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); sprintf (sz_cmd_buf_a, "open \"%s\" alias GNUEmacs_PlaySound_Device wait", fname_to_use); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); } } else { wchar_t sz_cmd_buf_w[520]; wchar_t sz_ret_buf_w[520]; wchar_t fname_w[MAX_PATH]; filename_to_utf16 (psz_file, fname_w); memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w)); memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w)); /* _swprintf is not available on Windows 9X, so we construct the UTF-16 command string by hand. */ wcscpy (sz_cmd_buf_w, L"open \""); wcscat (sz_cmd_buf_w, fname_w); wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringW (sz_cmd_buf_w, sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL); } if (mci_error != 0) { strcpy (warn_text, "mciSendString: 'open' command failed to open sound file "); strcat (warn_text, psz_file); SOUND_WARNING (mciGetErrorString, mci_error, warn_text); i_result = (int) mci_error; return i_result; } if ((ui_volume > 0) && (ui_volume != UINT_MAX)) { mm_result = waveOutGetVolume ((HWAVEOUT) WAVE_MAPPER, &ui_volume_org); if (mm_result == MMSYSERR_NOERROR) { b_reset_volume = TRUE; mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume); if (mm_result != MMSYSERR_NOERROR) { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutSetVolume: failed to set the volume level" " of the WAVE_MAPPER device.\n" "As a result, the user selected volume level will" " not be used."); } } else { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutGetVolume: failed to obtain the original" " volume level of the WAVE_MAPPER device.\n" "As a result, the user selected volume level will" " not be used."); } } memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); if (mci_error != 0) { strcpy (warn_text, "mciSendString: 'play' command failed to play sound file "); strcat (warn_text, psz_file); SOUND_WARNING (mciGetErrorString, mci_error, warn_text); i_result = (int) mci_error; } memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a)); memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a)); strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait"); mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL); if (b_reset_volume == TRUE) { mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org); if (mm_result != MMSYSERR_NOERROR) { SOUND_WARNING (waveOutGetErrorText, mm_result, "waveOutSetVolume: failed to reset the original" " volume level of the WAVE_MAPPER device."); } } return i_result; }
// // Opendir with wildcard pattern, for network speedup // // Called by glob.c // static DIR* __opendir_with_pat(const char* szPath, const char* szPat, BOOL bCache) { char szBuf[FILENAME_MAX]; char szFullDirPath[FILENAME_MAX]; char szPatBuf[FILENAME_MAX+10]; char* sz; struct cache_dir *cd; struct cache_entry *ce; DIR* pDir; long hFind; struct _finddatai64_t fd; BOOL bShowStreams = (show_streams == yes_arg); BOOL bFixedDisk = FALSE; BOOL bGetFullFileInfoOk = TRUE; // // Delete the previous non-cached dir, if any // if (_dir_nocache != NULL) { _delete_dir(_dir_nocache); _dir_nocache = NULL; } lstrcpyn(szBuf, szPath, sizeof(szBuf)); // // Change forward slashes to backward slashes // for (sz = szBuf; *sz; ++sz) { if (*sz == '/') { *sz = '\\'; } } // // Strip trailing backslashes // for (--sz; sz > szBuf; --sz) { if (*sz != '\\') { break; } if (sz == szBuf+2 && szBuf[1] == ':') { break; // stop if C:\ } *sz = '\0'; } if (!gbReg) { // // See if the pattern contains any UNIX-style glob chars // other than *? // // Note that '!' is legal in an NTFS file name. // // Note that all glob chars are legal in registry names. // if (_mbspbrk(szPat, "[]+@") != NULL) { szPat = "*"; // punt } } // // Return cached dir if available // if ((cd = _find_cache_dir(szBuf, szPat)) != NULL) { pDir = xmalloc(sizeof(DIR)); memset(pDir, 0, sizeof(pDir)); pDir->dd_cd = cd; pDir->dd_next_entry = cd->cd_entry_first; return pDir; } // // Get the absolute path of the directory for FindFirst // if (_GetAbsolutePath(szBuf, szFullDirPath, FILENAME_MAX, &bFixedDisk) < 0) { return NULL; } // // Do not show streams if --fast on a non-fixed disk // if (run_fast && !bFixedDisk) { bShowStreams = FALSE; } // // See if the resulting path is too long // if (strlen(szBuf) + strlen(szPat) + 2 > sizeof(szBuf)) { errno = ENAMETOOLONG; return NULL; } // // Create a new directory node // cd = (struct cache_dir *)xmalloc(sizeof(struct cache_dir)); memset(cd, 0, sizeof(*cd)); cd->cd_dirname = xstrdup(szBuf); // *not* abs path - must match for caching cd->cd_pat = xstrdup(szPat); // // Append search pattern for FindFirstFile. // Use absolute path to make sure it works w/UNC // strcpy(szPatBuf, szFullDirPath); if (*right(szPatBuf, 1) != '\\') { // if not already strcat(szPatBuf, "\\"); } strcat(szPatBuf, szPat); #ifdef UNDEFINED // // BUG: FindFirst("\\server\share") fails! Must append // a backslash, "\\server\share\" // if (_IsServerRootPath(szPatBuf)) { sz = szPatBuf + strlen(szPatBuf) - 1; if (*sz != '\\') { *++sz = '\\'; *++sz = '\0'; } } #endif #ifdef _DEBUG #define DEBUG_FINDFIRST #endif #ifdef DEBUG_FINDFIRST more_printf("opendir: findfirst on \"%s\"\n", szPatBuf); more_fflush(stdmore); #endif // // Always guaranteed to return at least "." and "..", otherwise // not a directory or not found. // if ((hFind = _xfindfirsti64(szPatBuf, &fd, bShowStreams, DT_DIR)) == (long)INVALID_HANDLE_VALUE) { MapWin32ErrorToPosixErrno(); free(cd->cd_dirname); free(cd->cd_pat); free(cd); return NULL; } if (bCache) { // // Append new directory to the dir cache list // if (_dir_first == NULL) { _dir_first = _dir_last = cd; } else { _dir_last->cd_next = cd; _dir_last = cd; } _dir_nocache = NULL; } else { // // Save as non-cached // _dir_nocache = cd; } do { // // Append each file entry to the dir // ce = (struct cache_entry *)xmalloc(sizeof(*ce)); memset(ce, 0, sizeof(*ce)); if (cd->cd_entry_first == NULL) { cd->cd_entry_first = cd->cd_entry_last = ce; } else { cd->cd_entry_last->ce_next = ce; cd->cd_entry_last = ce; } ce->ce_filename = (char *)xstrdup(fd.name); ce->ce_size = fd.size; ce->ce_ino = 1; // requires GetFileInformationByHandle - uintmax_t ce->dwFileAttributes = fd.attrib; // FILE_ATTRIBUTE_NORMAL maps to 0 ce->ce_atime = fd.time_access; ce->ce_mtime = fd.time_write; ce->ce_ctime = fd.time_create; ce->nNumberOfLinks = 1; if (bFixedDisk) { ce->dwFileAttributes |= FILE_ATTRIBUTE_FIXED_DISK; } // Flag reparse points and .LNK shortcuts as symbolic links if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 || _mbsicmp(right(fd.name, 4), ".lnk") == 0) { ce->ce_bIsSymlink = TRUE; } // // If we are reparse point, or need full info, // or phys size, or short names, or ls -l // if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 || gbReg || !run_fast || bFixedDisk || print_inode || phys_size || short_names) { char szBuf2[FILENAME_MAX], szBuf3[FILENAME_MAX]; // // Build dir\file // if (strlen(szFullDirPath) + strlen(fd.name) + 2 < sizeof(szBuf2)) { strcpy(szBuf2, szFullDirPath); // directory path if (*right(szBuf2, 1) != '\\') { // if not already strcat(szBuf2, "\\"); } strcat(szBuf2, fd.name); // // Get the absolute path // if (_GetAbsolutePath(szBuf2, szBuf3, FILENAME_MAX, NULL) >= 0) { // // Squirrel away our abs path for later lookup by security.cpp // ce->ce_abspath = xstrdup(szBuf3); if (gbReg && (ce->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // For registry keys we must test each regkey explicitly _follow_symlink(ce); } if ((!run_fast || bFixedDisk || print_inode) && bGetFullFileInfoOk) { // // Get inode and hardlink info // (requires absolute path) // bGetFullFileInfoOk = (_get_full_file_info(szBuf3, ce) == 0); } } // // Get the physical size too if requested // if (phys_size) { ce->ce_size = _get_phys_size(szBuf2, ce->ce_size); } if (short_names) { // // Get the short path, then extract the rightmost // component and stuff it into ce->ce_filename // _get_short_path(szBuf2); if ((sz = strrchr(szBuf2, '\\')) != NULL) { ++sz; free(ce->ce_filename); ce->ce_filename = (char *)xstrdup(sz); } } } } } while (_xfindnexti64(hFind, &fd, bShowStreams) != -1); if (GetLastError() != ERROR_NO_MORE_FILES) { // network fail during walk DWORD dwError = GetLastError(); _xfindclose(hFind, bShowStreams); SetLastError(dwError); MapWin32ErrorToPosixErrno(); return NULL; } if (_xfindclose(hFind, bShowStreams) == -1) { MapWin32ErrorToPosixErrno(); return NULL; } // // Build and return DIR // pDir = xmalloc(sizeof(DIR)); memset(pDir, 0, sizeof(pDir)); pDir->dd_cd = cd; pDir->dd_next_entry = cd->cd_entry_first; return pDir; }
static int __xstat(const char *szPath, struct xstat *st, unsigned long dwType, BOOL bCache, BOOL bFollowSymlink) { char szFullPath[FILENAME_MAX], szBuf[FILENAME_MAX]; char szDirBuf[FILENAME_MAX]; char *sz, *szDir, *szFile; struct cache_dir *cd; struct cache_entry *ce; long hFind; struct _finddatai64_t fd; BOOL bShowStreams = (show_streams == yes_arg); BOOL bFixedDisk = FALSE; lstrcpyn(szFullPath, szPath, FILENAME_MAX); // // Change forward slashes to backward slashes // for (sz = szFullPath; *sz; ++sz) { if (*sz == '/') { *sz = '\\'; } } // // Strip trailing backslashes // for (--sz; sz > szFullPath; --sz) { if (*sz != '\\') { break; } if (sz == szFullPath+2 && szFullPath[1] == ':') { break; // stop if C:\ } *sz = '\0'; } // // No FindFile wildcards allowed at this point // if (_mbspbrk(szFullPath, "?*") != NULL) { errno = ENOENT; return -1; } // // Break off dir and file components // strcpy(szBuf, szFullPath); if ((sz = strrchr(szBuf, '\\')) == NULL) { if (szBuf[1] == ':') { if (szBuf[2] == '\0') { // ls C: szDir = szBuf; // C: szFile = "."; } else { // ls C:foo szDirBuf[0] = szBuf[0]; szDirBuf[1] = szBuf[1]; szDirBuf[2] = '\0'; szDir = szDirBuf; // C: szFile = szBuf+2; // foo } } else { // ls foo szDir = "."; szFile = szBuf; } } else { // ls dir\foo szFile = sz+1; // // Strip trailing backslashes from the dir component // strcpy(szDirBuf, szBuf); // copy to avoid stomping on szFile szDir = szDirBuf; sz = szDir + (sz-szBuf); *(sz+1) = '\0'; // ensure termination for (; *sz == '\\' && sz > szDirBuf; --sz) { if (sz == szDirBuf+2 && szDirBuf[1] == ':') { break; // stop if C:\ } *sz = '\0'; } } if ((cd = _find_cache_dir(szDir, szFile)) != NULL) { // // Found hit from previous opendir()/readdir() // for (ce = cd->cd_entry_first; ce; ce = ce->ce_next) { if (ce->ce_filename[0] == szFile[0] && _mbsicmp(ce->ce_filename, szFile) == 0) { // // Found file // goto cache_hit; } } errno = ENOENT; // not in cache dir return -1; } // // Get the canonical path for use in security.cpp // if (_GetAbsolutePath(szFullPath, szBuf, FILENAME_MAX, &bFixedDisk) < 0) { return -1; } strcpy(szFullPath, szBuf); // // Check the partial stat cache against the abs path // for (ce = _stat_first; ce; ce = ce->ce_next) { if (ce->ce_abspath && _mbsicmp(ce->ce_abspath, szFullPath) == 0) { goto cache_hit; } } // // Do not show streams if --fast on a non-fixed disk // if (run_fast && !bFixedDisk) { bShowStreams = FALSE; } #ifdef DEBUG_FINDFIRST more_printf("stat: findfirst on \"%s\"\n", szFullPath); more_fflush(stdmore); #endif // // Do a singleton FindFirst to get WIN32_FILE_DATA // if ((hFind = _xfindfirsti64(szFullPath, &fd, bShowStreams, dwType)) != (long)INVALID_HANDLE_VALUE) { // Succeeded if (_xfindclose(hFind, bShowStreams) == -1) { MapWin32ErrorToPosixErrno(); return -1; } } else { // // FindFirst failed. This is a normal (sic) error for root folders // e.g., C:\ and sometimes \\server\share\ // if ((szFullPath[1] == ':' && szFullPath[2] == '\\' && szFullPath[3] == '\0') || _IsServerRootPath(szFullPath)) { // // Fake an entry for the root folder // time_t t; memset(&fd, 0, sizeof(fd)); t = time(0); fd.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM; strcpy(fd.name, "\\"); fd.time_access = t; fd.time_write = t; fd.time_create = t; } else { MapWin32ErrorToPosixErrno(); return -1; } } ce = (struct cache_entry *)xmalloc(sizeof(*ce)); memset(ce, 0, sizeof(*ce)); if (bCache) { // // Put on the partial stat cache // if (_stat_first == NULL) { _stat_first = _stat_last = ce; } else { _stat_last->ce_next = ce; _stat_last = ce; } } if (short_names) { _get_short_path(szFullPath); // update in place } ce->ce_filename = (char *)xstrdup(fd.name); // last component only ce->ce_size = fd.size; ce->ce_ino = 1; // requires GetFileInformationByHandle - uintmax_t ce->dwFileAttributes = fd.attrib; // FILE_ATTRIBUTE_NORMAL maps to 0 ce->ce_atime = fd.time_access; ce->ce_mtime = fd.time_write; ce->ce_ctime = fd.time_create; ce->nNumberOfLinks = 1; if (bFixedDisk) { ce->dwFileAttributes |= FILE_ATTRIBUTE_FIXED_DISK; } // // Squirrel away the canonical path // ce->ce_abspath = xstrdup(szFullPath); // Flag reparse points and .LNK shortcuts as symbolic links if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 || _mbsicmp(right(fd.name, 4), ".lnk") == 0) { ce->ce_bIsSymlink = TRUE; } if (phys_size) { ce->ce_size = _get_phys_size(szFullPath, ce->ce_size); } if (!run_fast || bFixedDisk || print_inode) { // // Get inode and hardlink info // _get_full_file_info(szFullPath, ce); } cache_hit: if (bFollowSymlink) { ce = _follow_symlink(ce); } memset(st, 0, sizeof(*st)); st->st_ino = ce->ce_ino; st->st_size = ce->ce_size; st->st_atime = ce->ce_atime; st->st_mtime = ce->ce_mtime; st->st_ctime = ce->ce_ctime; st->st_nlink = (short)ce->nNumberOfLinks; st->st_mode = _MapMode(ce); st->st_ce = ce; return 0; }
_WCRTLINK int stat( CHAR_TYPE const *path, struct stat *buf ) { const CHAR_TYPE * ptr; CHAR_TYPE fullpath[_MAX_PATH]; CHAR_TYPE * fullp; int isrootdir = 0; int handle; int RdosAttrib; int ok; CHAR_TYPE name[_MAX_PATH]; int attrib; unsigned long wr_msb; unsigned long wr_lsb; long size; int ms; int us; struct tm tm; int i; /* reject null string and names that has wildcard */ if( *path == '\0' || _mbspbrk( path, "*?" ) != NULL ) return( -1 ); /*** Determine if 'path' refers to a root directory ***/ if( _fullpath( fullpath, path, _MAX_PATH ) != NULL ) { if( isalpha( fullpath[0] ) && fullpath[1] == ':' && fullpath[2] == '\\' && fullpath[3] == '\0' ) { isrootdir = 1; } } else return( -1 ); ptr = path; if( *_mbsinc(path ) ) ptr += 2; if( ( (ptr[0] == '\\' || ptr[0] == '/') && ptr[1] == '\0' ) || isrootdir ) { /* handle root directory */ CHAR_TYPE cwd[_MAX_PATH]; /* save current directory */ getcwd( cwd, _MAX_PATH ); /* try to change to specified root */ if( chdir( path ) != 0 ) return( -1 ); /* restore current directory */ chdir( cwd ); attrib = _A_SUBDIR; wr_msb = 0; wr_lsb = 0; size = 0; name[0] = NULLCHAR; } else { /* not a root directory */ fullp = fullpath + strlen( fullpath ) - 1; while( *fullp != '\\' && *fullp != '/' && fullp != fullpath ) fullp--; *fullp = 0; fullp++; if( strlen( fullpath ) == 0 ) strcpy( fullpath, "*" ); handle = RdosOpenDir( fullpath ); ok = 0; i = 0; strlwr( fullp ); while( RdosReadDir( handle, i, _MAX_PATH, name, &size, &RdosAttrib, &wr_msb, &wr_lsb ) ) { strlwr( name ); if( !strcmp( name, fullp ) ) { ok = 1; break; } i++; } RdosCloseDir( handle ); if( !ok ) return( -1 ); attrib = 0; if( RdosAttrib & FILE_ATTRIBUTE_ARCHIVE ) { attrib |= _A_ARCH; } if( RdosAttrib & FILE_ATTRIBUTE_DIRECTORY ) { attrib |= _A_SUBDIR; } if( RdosAttrib & FILE_ATTRIBUTE_HIDDEN ) { attrib |= _A_HIDDEN; } if( RdosAttrib & FILE_ATTRIBUTE_NORMAL ) { attrib |= _A_NORMAL; } if( RdosAttrib & FILE_ATTRIBUTE_READONLY ) { attrib |= _A_RDONLY; } if( RdosAttrib & FILE_ATTRIBUTE_SYSTEM ) { attrib |= _A_SYSTEM; } } /* process drive number */ if( *_mbsinc(path) ) { buf->st_dev = tolower( fullpath[0] ) - 'a'; } else { buf->st_dev = RdosGetCurDrive(); } buf->st_rdev = buf->st_dev; buf->st_size = size; buf->st_mode = at2mode( attrib, name ); RdosDecodeMsbTics( wr_msb, &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour ); RdosDecodeLsbTics( wr_lsb, &tm.tm_min, &tm.tm_sec, &ms, &us ); tm.tm_year -= 1900; tm.tm_mon--; tm.tm_isdst = -1; tm.tm_wday = -1; tm.tm_yday = -1; buf->st_mtime = mktime( &tm ); buf->st_atime = buf->st_ctime = buf->st_btime = buf->st_mtime; buf->st_nlink = 1; buf->st_ino = buf->st_uid = buf->st_gid = 0; buf->st_attr = attrib; buf->st_archivedID = 0; buf->st_updatedID = 0; buf->st_inheritedRightsMask = 0; buf->st_originatingNameSpace = 0; return( 0 ); }
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; }