Index: /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
===================================================================
--- /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c	(revision 30416)
+++ /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c	(revision 30417)
@@ -521,4 +521,168 @@
 }
 
+static void
+sfprov_timespec_from_ftime(RTTIMESPEC *ts, timestruc_t time)
+{
+	uint64_t nanosec = 1000000000 * time.tv_sec + time.tv_nsec;
+	RTTimeSpecSetNano(ts, nanosec);
+}
+
+int
+sfprov_set_attr(
+	sfp_mount_t *mnt,
+	char *path,
+	uint_t mask,
+	mode_t mode,
+	timestruc_t atime,
+	timestruc_t mtime,
+	timestruc_t ctime)
+{
+	int rc, err;
+	SHFLCREATEPARMS parms;
+	SHFLSTRING *str;
+	RTFSOBJINFO info;
+	uint32_t bytes;
+	int str_size;
+
+	str = sfprov_string(path, &str_size);
+	parms.Handle = 0;
+	parms.Info.cbObject = 0;
+	parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
+			  | SHFL_CF_ACT_FAIL_IF_NEW
+			  | SHFL_CF_ACCESS_ATTR_WRITE;
+
+	rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
+
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_attr: vboxCallCreate(%s) failed rc=%d",
+		    path, rc);
+		err = EINVAL;
+		goto fail2;
+	}
+	if (parms.Result != SHFL_FILE_EXISTS) {
+		err = ENOENT;
+		goto fail1;
+	}
+
+	RT_ZERO(info);
+	if (mask & AT_MODE) {
+#define mode_set(r) ((mode & (S_##r)) ? RTFS_UNIX_##r : 0)
+
+		info.Attr.fMode  = mode_set (ISUID);
+		info.Attr.fMode |= mode_set (ISGID);
+		info.Attr.fMode |= (mode & S_ISVTX) ? RTFS_UNIX_ISTXT : 0;
+		info.Attr.fMode |= mode_set (IRUSR);
+		info.Attr.fMode |= mode_set (IWUSR);
+		info.Attr.fMode |= mode_set (IXUSR);
+		info.Attr.fMode |= mode_set (IRGRP);
+		info.Attr.fMode |= mode_set (IWGRP);
+		info.Attr.fMode |= mode_set (IXGRP);
+		info.Attr.fMode |= mode_set (IROTH);
+		info.Attr.fMode |= mode_set (IWOTH);
+		info.Attr.fMode |= mode_set (IXOTH);
+
+		if (S_ISDIR(mode))
+			info.Attr.fMode |= RTFS_TYPE_DIRECTORY;
+		else if (S_ISREG(mode))
+			info.Attr.fMode |= RTFS_TYPE_FILE;
+		else if (S_ISFIFO(mode))
+			info.Attr.fMode |= RTFS_TYPE_FIFO;
+		else if (S_ISCHR(mode))
+			info.Attr.fMode |= RTFS_TYPE_DEV_CHAR;
+		else if (S_ISBLK(mode))
+			info.Attr.fMode |= RTFS_TYPE_DEV_BLOCK;
+		else if (S_ISLNK(mode))
+			info.Attr.fMode |= RTFS_TYPE_SYMLINK;
+		else if (S_ISSOCK(mode))
+			info.Attr.fMode |= RTFS_TYPE_SOCKET;
+		else
+			info.Attr.fMode |= RTFS_TYPE_FILE;
+	}
+
+	if (mask & AT_ATIME)
+		sfprov_timespec_from_ftime(&info.AccessTime, atime);
+	if (mask & AT_MTIME)
+		sfprov_timespec_from_ftime(&info.ModificationTime, mtime);
+	if (mask & AT_CTIME)
+		sfprov_timespec_from_ftime(&info.ChangeTime, ctime);
+
+	bytes = sizeof(info);
+	rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle,
+	    (SHFL_INFO_SET | SHFL_INFO_FILE), &bytes, (SHFLDIRINFO *)&info);
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_attr: vboxCallFSInfo(%s, FILE) failed rc=%d",
+		    path, rc);
+		err = RTErrConvertToErrno(rc);
+		goto fail1;
+	}
+
+	err = 0;
+
+fail1:
+	rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle);
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_attr: vboxCallClose(%s) failed rc=%d",
+		    path, rc);
+	}
+fail2:
+	kmem_free(str, str_size);
+	return err;
+}
+
+int
+sfprov_set_size(sfp_mount_t *mnt, char *path, uint64_t size)
+{
+	int rc, err;
+	SHFLCREATEPARMS parms;
+	SHFLSTRING *str;
+	RTFSOBJINFO info;
+	uint32_t bytes;
+	int str_size;
+
+	str = sfprov_string(path, &str_size);
+	parms.Handle = 0;
+	parms.Info.cbObject = 0;
+	parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
+			  | SHFL_CF_ACT_FAIL_IF_NEW
+			  | SHFL_CF_ACCESS_WRITE;
+
+	rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
+
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_size: vboxCallCreate(%s) failed rc=%d",
+		    path, rc);
+		err = EINVAL;
+		goto fail2;
+	}
+	if (parms.Result != SHFL_FILE_EXISTS) {
+		err = ENOENT;
+		goto fail1;
+	}
+
+	RT_ZERO(info);
+	info.cbObject = size;
+	bytes = sizeof(info);
+	rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle,
+	    (SHFL_INFO_SET | SHFL_INFO_SIZE), &bytes, (SHFLDIRINFO *)&info);
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_size: vboxCallFSInfo(%s, SIZE) failed rc=%d",
+		    path, rc);
+		err = RTErrConvertToErrno(rc);
+		goto fail1;
+	}
+
+	err = 0;
+
+fail1:
+	rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle);
+	if (RT_FAILURE(rc)) {
+		cmn_err(CE_WARN, "sfprov_set_size: vboxCallClose(%s) failed rc=%d",
+		    path, rc);
+	}
+fail2:
+	kmem_free(str, str_size);
+	return err;
+}
+
 /*
  * Directory operations
Index: /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
===================================================================
--- /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h	(revision 30416)
+++ /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h	(revision 30417)
@@ -2,4 +2,5 @@
 /** @file
  * VirtualBox File System for Solaris Guests, provider header.
+ * Portions contributed by: Ronald.
  */
 
@@ -86,5 +87,5 @@
 
 /*
- * get information about a file (or directory) using pathname
+ * get/set information about a file (or directory) using pathname
  */
 extern int sfprov_get_mode(sfp_mount_t *, char *, mode_t *);
@@ -93,4 +94,7 @@
 extern int sfprov_get_mtime(sfp_mount_t *, char *, timestruc_t *);
 extern int sfprov_get_ctime(sfp_mount_t *, char *, timestruc_t *);
+extern int sfprov_set_attr(sfp_mount_t *, char *, uint_t, mode_t,
+   timestruc_t, timestruc_t, timestruc_t);
+extern int sfprov_set_size(sfp_mount_t *, char *, uint64_t);
 
 
Index: /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
===================================================================
--- /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(revision 30416)
+++ /trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(revision 30417)
@@ -60,4 +60,5 @@
 #include <VBox/log.h>
 
+#include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -781,4 +782,71 @@
 }
 
+static int
+sffs_setattr(
+	vnode_t		*vp,
+	vattr_t		*vap,
+	int		flags,
+	cred_t		*cred,
+	caller_context_t *ct)
+{
+	sfnode_t	*node = VN2SFN(vp);
+	int		error;
+	mode_t		mode;
+
+	mode = vap->va_mode;
+	if (vp->v_type == VREG)
+		mode |= S_IFREG;
+	else if (vp->v_type == VDIR)
+		mode |= S_IFDIR;
+	else if (vp->v_type == VBLK)
+		mode |= S_IFBLK;
+	else if (vp->v_type == VCHR)
+		mode |= S_IFCHR;
+	else if (vp->v_type == VLNK)
+		mode |= S_IFLNK;
+	else if (vp->v_type == VFIFO)
+		mode |= S_IFIFO;
+	else if (vp->v_type == VSOCK)
+		mode |= S_IFSOCK;
+
+	mutex_enter(&sffs_lock);
+
+	error = sfprov_set_attr(node->sf_sffs->sf_handle, node->sf_path,
+	    vap->va_mask, mode, vap->va_atime, vap->va_mtime, vap->va_ctime);
+	if (error == ENOENT)
+		sfnode_make_stale(node);
+
+	mutex_exit(&sffs_lock);
+	return (error);
+}
+
+static int
+sffs_space(
+	vnode_t		*vp,
+	int		cmd,
+	struct flock64	*bfp,
+	int		flags,
+	offset_t	off,
+	cred_t		*cred,
+	caller_context_t *ct)
+{
+	sfnode_t	*node = VN2SFN(vp);
+	int		error;
+
+	/* we only support changing the length of the file */
+	if (bfp->l_whence != SEEK_SET || bfp->l_len != 0)
+		return ENOSYS;
+
+	mutex_enter(&sffs_lock);
+
+	error = sfprov_set_size(node->sf_sffs->sf_handle, node->sf_path,
+	    bfp->l_start);
+	if (error == ENOENT)
+		sfnode_make_stale(node);
+
+	mutex_exit(&sffs_lock);
+	return (error);
+}
+
 /*ARGSUSED*/
 static int
@@ -1512,4 +1580,6 @@
 	VOPNAME_RMDIR,		sffs_rmdir,
 	VOPNAME_SEEK,		sffs_seek,
+	VOPNAME_SETATTR,	sffs_setattr,
+	VOPNAME_SPACE,		sffs_space,
 	VOPNAME_WRITE,		sffs_write,
 	NULL,			NULL
@@ -1532,4 +1602,6 @@
 	VOPNAME_RMDIR,		{ .vop_rmdir = sffs_rmdir },
 	VOPNAME_SEEK,		{ .vop_seek = sffs_seek },
+	VOPNAME_SETATTR,	{ .vop_setattr = sffs_setattr },
+	VOPNAME_SPACE,		{ .vop_space = sffs_space },
 	VOPNAME_WRITE,		{ .vop_write = sffs_write },
 	NULL,			NULL
