Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
//
// 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;
}
Пример #4
0
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;
}
Пример #5
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 );
}
Пример #6
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;
}