Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
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;
}