/** * Check if VFS object exists on a host side. * * @param vnode Guest VFS vnode that corresponds to host VFS object * * @return 1 if exists, 0 otherwise. */ int vboxvfs_exist_internal(vnode_t vnode) { int rc; PSHFLSTRING pSFPath = NULL; SHFLHANDLE handle; uint32_t fFlags; vboxvfs_mount_t *pMount; mount_t mp; /* Return FALSE if invalid parameter given */ AssertReturn(vnode, 0); mp = vnode_mount(vnode); AssertReturn(mp, EINVAL); pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp); AssertReturn(pMount, EINVAL); fFlags = (vnode_isdir(vnode)) ? SHFL_CF_DIRECTORY : 0; fFlags |= SHFL_CF_ACCESS_READ | SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; rc = vboxvfs_guest_vnode_to_shflstring_path_internal(vnode, &pSFPath); AssertReturn(rc == 0, rc); if (rc == 0) { rc = vboxvfs_open_internal(pMount, pSFPath, fFlags, &handle); if (rc == 0) { rc = vboxvfs_close_internal(pMount, handle); if (rc != 0) { PDEBUG("Unable to close() VBoxVFS object handle while checking if object exist on host: %d", rc); } } } vboxvfs_put_path_internal((void **)&pSFPath); return (rc == 0); }
/** * Convert guest absolute VFS path (starting from VFS root) to a host path * within mounted shared folder. * * @param mp Mount data structure * @param pszGuestPath Guest absolute VFS path (starting from VFS root) * @param cbGuestPath Size of pszGuestPath * @param ppResult Returned PSHFLSTRING object wich contains host path * * @return 0 on success, error code otherwise */ int vboxvfs_guest_path_to_shflstring_path_internal(mount_t mp, char *pszGuestPath, int cbGuestPath, PSHFLSTRING *ppResult) { vboxvfs_mount_t *pMount; /* Guest side: mount point path buffer and its size */ char *pszMntPointPath; int cbMntPointPath = MAXPATHLEN; /* Host side: path within mounted shared folder and its size */ PSHFLSTRING pSFPath; size_t cbSFPath; int rc; AssertReturn(mp, EINVAL); AssertReturn(pszGuestPath, EINVAL); AssertReturn(cbGuestPath >= 0, EINVAL); char *pszHostPath; int cbHostPath; rc = vboxvfs_guest_path_to_char_path_internal(mp, pszGuestPath, cbGuestPath, &pszHostPath, &cbHostPath); if (rc == 0) { cbSFPath = offsetof(SHFLSTRING, String.utf8) + (size_t)cbHostPath + 1; pSFPath = (PSHFLSTRING)RTMemAllocZ(cbSFPath); if (pSFPath) { pSFPath->u16Length = cbHostPath; pSFPath->u16Size = cbHostPath + 1; memcpy(pSFPath->String.utf8, pszHostPath, cbHostPath); vboxvfs_put_path_internal((void **)&pszHostPath); *ppResult = pSFPath; } } return rc; }
/** * Helper function for vboxvfs_vnode_lookup(): create new vnode. */ static int vboxvfs_vnode_lookup_instantinate_vnode(vnode_t parent_vnode, char *entry_name, vnode_t *result_vnode) { /* We need to construct full path to vnode in order to get * vboxvfs_get_info_internal() to understand us! */ char *pszCurDirPath; int cbCurDirPath = MAXPATHLEN; mount_t mp = vnode_mount(parent_vnode); AssertReturn(mp, EINVAL); vnode_t vnode; int rc; pszCurDirPath = (char *)RTMemAllocZ(cbCurDirPath); if (pszCurDirPath) { rc = vn_getpath(parent_vnode, pszCurDirPath, &cbCurDirPath); if (rc == 0 && cbCurDirPath < MAXPATHLEN) { SHFLFSOBJINFO Info; PSHFLSTRING pSHFLPath; /* Add '/' between path parts and truncate name if it is too long */ strncat(pszCurDirPath, "/", 1); strncat(pszCurDirPath, entry_name, MAXPATHLEN - cbCurDirPath - 1); rc = vboxvfs_guest_path_to_shflstring_path_internal(mp, pszCurDirPath, strlen(pszCurDirPath) + 1, &pSHFLPath); if (rc == 0) { rc = vboxvfs_get_info_internal(mp, pSHFLPath, (PSHFLFSOBJINFO)&Info); if (rc == 0) { enum vtype type; if (RTFS_IS_DIRECTORY(Info.Attr.fMode)) type = VDIR; else if (RTFS_IS_FILE (Info.Attr.fMode)) type = VREG; else { PDEBUG("Not supported VFS object (%s) type: mode 0x%X", entry_name, Info.Attr.fMode); RTMemFree(pszCurDirPath); vboxvfs_put_path_internal((void **)&pSHFLPath); return ENOENT; } /* Create new vnode */ rc = vboxvfs_create_vnode_internal(mp, type, parent_vnode, FALSE, pSHFLPath, &vnode); if (rc == 0) { PDEBUG("new vnode object '%s' has been created", entry_name); *result_vnode = vnode; RTMemFree(pszCurDirPath); return 0; } else PDEBUG("Unable to create vnode: %d", rc); } else PDEBUG("Unable to get host object info: %d", rc); vboxvfs_put_path_internal((void **)&pSHFLPath); } else PDEBUG("Unable to convert guest<->host path"); } else PDEBUG("Unable to construct vnode path: %d", rc); RTMemFree(pszCurDirPath); } else { PDEBUG("Unable to allocate memory for path buffer"); rc = ENOMEM; } return rc; }