int impl_fuse_context::unlock_file(LPCWSTR file_name, LONGLONG byte_offset, LONGLONG length, PDOKAN_FILE_INFO dokan_file_info) { impl_file_handle *hndl = reinterpret_cast<impl_file_handle *>(dokan_file_info->Context); if (!hndl) return -EINVAL; if (hndl->is_dir()) return -EACCES; FUSE_OFF_T off; CHECKED(cast_from_longlong(byte_offset, &off)); if (ops_.lock) { fuse_file_info finfo(hndl->make_finfo()); struct flock lock; lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = off; lock.l_len = length; return ops_.lock(hndl->get_name().c_str(), &finfo, F_SETLK, &lock); } return hndl->unlock(byte_offset, length); }
int impl_fuse_context::write_file(LPCWSTR /*file_name*/, LPCVOID buffer, DWORD num_bytes_to_write,LPDWORD num_bytes_written, LONGLONG offset, PDOKAN_FILE_INFO dokan_file_info) { //Please note, that we ifnore file_name here, because it might //have been retargeted by a symlink. *num_bytes_written=0; //Conform to ReadFile semantics if (!ops_.write) return -EINVAL; impl_file_handle *hndl=reinterpret_cast<impl_file_handle*>(dokan_file_info->Context); if (!hndl) return -EINVAL; if (hndl->is_dir()) return -EACCES; //Clip the maximum write size if (num_bytes_to_write>conn_info_.max_write) num_bytes_to_write=conn_info_.max_write; FUSE_OFF_T off; CHECKED(cast_from_longlong(offset,&off)); fuse_file_info finfo(hndl->make_finfo()); int res=ops_.write(hndl->get_name().c_str(),(const char*)buffer, num_bytes_to_write, off,&finfo); if (res<0) return res; //Error //OK! *num_bytes_written=res; return 0; }
int impl_fuse_context::read_file(LPCWSTR /*file_name*/, LPVOID buffer, DWORD num_bytes_to_read, LPDWORD read_bytes, LONGLONG offset, PDOKAN_FILE_INFO dokan_file_info) { // Please note, that we ignore file_name here, because it might // have been retargeted by a symlink. if (!ops_.read) return -EINVAL; *read_bytes = 0; // Conform to ReadFile semantics impl_file_handle *hndl = reinterpret_cast<impl_file_handle *>(dokan_file_info->Context); if (!hndl) return -EINVAL; if (hndl->is_dir()) return -EACCES; // check locking if (hndl->check_lock(offset, num_bytes_to_read)) return -EACCES; FUSE_OFF_T off; CHECKED(cast_from_longlong(offset, &off)); fuse_file_info finfo(hndl->make_finfo()); DWORD total_read = 0; while (total_read < num_bytes_to_read) { DWORD to_read = num_bytes_to_read - total_read; if (to_read > MAX_READ_SIZE) to_read = MAX_READ_SIZE; int res = ops_.read(hndl->get_name().c_str(), (char *)buffer, to_read, off, &finfo); if (res < 0) return res; // Error if (res == 0) break; // End of file reached total_read += res; off += res; buffer = (char *)buffer + res; } // OK! *read_bytes = total_read; return 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); }