Beispiel #1
0
int impl_fuse_context::set_file_time(PCWSTR file_name,
                                     const FILETIME *creation_time,
                                     const FILETIME *last_access_time,
                                     const FILETIME *last_write_time,
                                     PDOKAN_FILE_INFO dokan_file_info) {
  if (!ops_.utimens && !ops_.utime && !ops_.win_set_times)
    return -EINVAL;

  if (ops_.win_set_times) {
    std::string fname = unixify(wchar_to_utf8_cstr(file_name));
    CHECKED(check_and_resolve(&fname));

    impl_file_handle *hndl =
        reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
    if (!hndl)
      return ops_.win_set_times(fname.c_str(), NULL, creation_time,
                                last_access_time, last_write_time);

    if (hndl->is_dir())
      return -EACCES;

    fuse_file_info finfo(hndl->make_finfo());

    return ops_.win_set_times(fname.c_str(), &finfo, creation_time,
                              last_access_time, last_write_time);
  }

  if (!ops_.getattr)
    return -EINVAL;

  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  CHECKED(check_and_resolve(&fname));

  struct FUSE_STAT st = {0};
  CHECKED(ops_.getattr(fname.c_str(), &st));

  if (ops_.utimens) {
    struct timespec tv[2] = {0};
    // TODO: support nanosecond resolution
    // Access time
    CHECKED(helper_set_time_struct(last_access_time, st.st_atim.tv_sec,
                                   &(tv[0].tv_sec)));
    // Modification time
    CHECKED(helper_set_time_struct(last_write_time, st.st_mtim.tv_sec,
                                   &(tv[1].tv_sec)));

    return ops_.utimens(fname.c_str(), tv);
  } else {
    struct utimbuf ut = {0};
    // Access time
    CHECKED(helper_set_time_struct(last_access_time, st.st_atim.tv_sec,
                                   &(ut.actime)));
    // Modification time
    CHECKED(helper_set_time_struct(last_write_time, st.st_mtim.tv_sec,
                                   &(ut.modtime)));

    return ops_.utime(fname.c_str(), &ut);
  }
}
Beispiel #2
0
int impl_fuse_context::set_file_time(PCWSTR file_name, const FILETIME* creation_time,
				  const FILETIME* last_access_time, const FILETIME* last_write_time,
				  PDOKAN_FILE_INFO dokan_file_info)
{
	if (!ops_.utimens && !ops_.utime) return -EINVAL;
	if (!ops_.getattr) return -EINVAL;

	std::string fname=unixify(wchar_to_utf8_cstr(file_name));
	CHECKED(check_and_resolve(&fname));

	struct FUSE_STAT st={0};
	CHECKED(ops_.getattr(fname.c_str(),&st));

	if (ops_.utimens)
	{
		struct timespec tv[2]={{0,},};
		//TODO: support nanosecond resolution
		//Access time
		CHECKED(helper_set_time_struct(last_access_time,st.st_atime,&(tv[0].tv_sec)));
		//Modification time
		CHECKED(helper_set_time_struct(last_write_time,st.st_mtime,&(tv[1].tv_sec)));

		return ops_.utimens(fname.c_str(),tv);
	} else
	{
		struct utimbuf ut={0};
		//Access time
		CHECKED(helper_set_time_struct(last_access_time,st.st_atime,&(ut.actime)));
		//Modification time
		CHECKED(helper_set_time_struct(last_write_time,st.st_mtime,&(ut.modtime)));

		return ops_.utime(fname.c_str(),&ut);
	}
}
Beispiel #3
0
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD Flags,
									PDOKAN_FILE_INFO DokanFileInfo)
{
	if (!ops_.open) return -EINVAL;
	std::string fname=unixify(wchar_to_utf8_cstr(FileName));
	CHECKED(check_and_resolve(&fname));

	fuse_file_info finfo={0};
	//if ((ShareMode & FILE_SHARE_READ) || (ShareMode & FILE_SHARE_DELETE))
	//TODO: add sharing support?
	finfo.flags=convert_flags(Flags);

	CHECKED(ops_.open(fname.c_str(),&finfo));
	DokanFileInfo->Context=reinterpret_cast<ULONG64>(new impl_file_handle(fname,false,&finfo));
	return 0;
}
Beispiel #4
0
int impl_fuse_context::set_file_attributes(LPCWSTR file_name,
                                           DWORD file_attributes,
                                           PDOKAN_FILE_INFO dokan_file_info) {
  // This method is unlikely to be implemented since we do not support
  // advanced properties
  // TODO: maybe use extended properties of underlying FS?

  // Just return 'success' since returning -EINVAL interferes with modification
  // time
  // setting from FAR Manager.
  if (ops_.win_set_attributes) {
    std::string fname = unixify(wchar_to_utf8_cstr(file_name));
    CHECKED(check_and_resolve(&fname));
    return ops_.win_set_attributes(fname.c_str(), file_attributes);
  }
  return 0;
}
Beispiel #5
0
int impl_fuse_context::set_end_of_file(LPCWSTR file_name, LONGLONG byte_offset,
                                       PDOKAN_FILE_INFO dokan_file_info) {
  FUSE_OFF_T off;
  CHECKED(cast_from_longlong(byte_offset, &off));
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  CHECKED(check_and_resolve(&fname));

  impl_file_handle *hndl =
      reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
  if (hndl && ops_.ftruncate) {
    fuse_file_info finfo(hndl->make_finfo());
    return ops_.ftruncate(hndl->get_name().c_str(), off, &finfo);
  }

  if (!ops_.truncate)
    return -EINVAL;
  return ops_.truncate(fname.c_str(), off);
}
Beispiel #6
0
int impl_fuse_context::find_files(LPCWSTR file_name,
                                  PFillFindData fill_find_data,
                                  PDOKAN_FILE_INFO dokan_file_info) {
  if ((!ops_.readdir && !ops_.getdir) || !ops_.getattr)
    return -EINVAL;

  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  CHECKED(check_and_resolve(&fname));

  walk_data wd;
  wd.ctx = this;
  wd.dirname = fname;
  if (*fname.rbegin() != '/')
    wd.dirname.append("/");
  wd.delegate = fill_find_data;
  wd.DokanFileInfo = dokan_file_info;

  if (ops_.readdir) {
    impl_file_handle *hndl =
        reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
    if (hndl != NULL) {
      fuse_file_info finfo(hndl->make_finfo());
      return ops_.readdir(fname.c_str(), &wd, &walk_directory, 0, &finfo);
    } else
      return ops_.readdir(fname.c_str(), &wd, &walk_directory, 0, NULL);
  } else {
    CHECKED(
        ops_.getdir(fname.c_str(), (fuse_dirh_t)&wd, &walk_directory_getdir));
    // Convert returned data The getdir_data array will be filled during
    // getdir() call.
    // We emulate FUSE behavior and do not pass information directly to Dokan
    // in walk_directory_getdir callback. This can cause excessive network
    // traffic
    // in sshfs because it populates stat buffer cache AFTER calling our
    // callback.
    // See: cache.c file, function cache_dirfill() in SSHFS 2.2
    for (std::vector<std::string>::const_iterator f = wd.getdir_data.begin();
         f != wd.getdir_data.end(); ++f)
      CHECKED(walk_directory(&wd, f->c_str(), 0, 0));
  }

  return 0;
}
Beispiel #7
0
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD share_mode, DWORD Flags,
									PDOKAN_FILE_INFO DokanFileInfo)
{
	if (!ops_.open) return -EINVAL;
	std::string fname=unixify(wchar_to_utf8_cstr(FileName));
	CHECKED(check_and_resolve(&fname));

	std::auto_ptr<impl_file_handle> file;
	CHECKED(file_locks.get_file(fname,false,Flags,share_mode,file));

	fuse_file_info finfo={0};
	finfo.flags=convert_flags(Flags);

	CHECKED(ops_.open(fname.c_str(),&finfo));

	file->set_finfo(finfo);
	DokanFileInfo->Context=reinterpret_cast<ULONG64>(file.release());
	return 0;
}