/** * Remove a regular file / directory. * * @param parent inode of the directory * @param dentry directory cache entry * @param fDirectory true if directory, false otherwise * @returns 0 on success, Linux error code otherwise */ static int sf_unlink_aux(struct inode *parent, struct dentry *dentry, int fDirectory) { int rc, err; struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb); struct sf_inode_info *sf_i = GET_INODE_INFO(parent); SHFLSTRING *path; uint32_t fFlags; TRACE(); BUG_ON(!sf_g); err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path); if (err) goto fail0; fFlags = fDirectory ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE; if ( dentry && dentry->d_inode && ((dentry->d_inode->i_mode & S_IFLNK) == S_IFLNK)) fFlags |= SHFL_REMOVE_SYMLINK; rc = vboxCallRemove(&client_handle, &sf_g->map, path, fFlags); if (RT_FAILURE(rc)) { LogFunc(("(%d): vboxCallRemove(%s) failed rc=%Rrc\n", fDirectory, path->String.utf8, rc)); err = -RTErrConvertToErrno(rc); goto fail1; } /* directory access/change time changed */ sf_i->force_restat = 1; /* directory content changed */ sf_i->force_reread = 1; err = 0; fail1: kfree(path); fail0: return err; }
NTSTATUS vbsfRemove(IN PRX_CONTEXT RxContext) { NTSTATUS Status = STATUS_SUCCESS; RxCaptureFcb; RxCaptureFobx; PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext); PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot); PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx); PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); int vboxRC; PSHFLSTRING ParsedPath = NULL; ULONG ParsedPathSize; Log(("VBOXSF: vbsfRemove: Delete %.*ls. open count = %d\n", RemainingName->Length / sizeof(WCHAR), RemainingName->Buffer, capFcb->OpenCount)); /* Close file first if not already done. */ if (pVBoxFobx->hFile != SHFL_HANDLE_NIL) { vbsfCloseFileHandle(pDeviceExtension, pNetRootExtension, pVBoxFobx); } /* Calculate length required for parsed path. */ ParsedPathSize = sizeof(*ParsedPath) + (RemainingName->Length + sizeof(WCHAR)); Log(("VBOXSF: vbsfRemove: ParsedPathSize %d\n", ParsedPathSize)); ParsedPath = (PSHFLSTRING)vbsfAllocNonPagedMem(ParsedPathSize); if (!ParsedPath) { return STATUS_INSUFFICIENT_RESOURCES; } ShflStringInitBuffer(ParsedPath, ParsedPathSize - sizeof(SHFLSTRING)); Log(("VBOXSF: vbsfRemove: Setup ParsedPath\n")); ParsedPath->u16Size = RemainingName->Length + sizeof(WCHAR); ParsedPath->u16Length = ParsedPath->u16Size - sizeof(WCHAR); /* without terminating null */ RtlCopyMemory(ParsedPath->String.ucs2, RemainingName->Buffer, ParsedPath->u16Length); /* Call host. */ vboxRC = vboxCallRemove(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, ParsedPath, (pVBoxFobx->FileStandardInfo.Directory) ? SHFL_REMOVE_DIR : SHFL_REMOVE_FILE); if (ParsedPath) { vbsfFreeNonPagedMem(ParsedPath); } if (vboxRC == VINF_SUCCESS) { SetFlag(capFobx->pSrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED); } Status = VBoxErrorToNTStatus(vboxRC); if (vboxRC != VINF_SUCCESS) { Log(("VBOXSF: vbsfRemove: vboxCallRemove failed with %Rrc\n", vboxRC)); } Log(("VBOXSF: vbsfRemove: Returned 0x%08X\n", Status)); return Status; }