Пример #1
0
static NTSTATUS vbsfWriteInternal(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);

    PLOWIO_CONTEXT LowIoContext  = &RxContext->LowIoContext;

    PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
    uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;

    PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);

    int vboxRC;

    BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
    LONGLONG FileSize;

    RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);

    Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
         AsyncIo, capFcb->Header.FileSize.QuadPart));
    Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
         pbUserBuffer, BufferMdl));
    Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
         ByteCount, ByteOffset, FileSize));

    /* @todo allow to write 0 bytes. */
    if (   BufferMdl == NULL
        || ByteCount == 0)
    {
        AssertFailed();
        return STATUS_INVALID_PARAMETER;
    }

    /* @todo Split large writes. */
    vboxRC = vboxCallWrite(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
                           ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);

    Status = VBoxErrorToNTStatus(vboxRC);

    if (Status != STATUS_SUCCESS)
    {
        /* Nothing written. */
        ByteCount = 0;
    }

    RxContext->InformationToReturn = ByteCount;

    Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
         Status, ByteCount));

    return Status;
}
Пример #2
0
NTSTATUS vbsfSetEndOfFile(IN OUT struct _RX_CONTEXT * RxContext,
                          IN OUT PLARGE_INTEGER pNewFileSize,
                          OUT PLARGE_INTEGER pNewAllocationSize)
{
    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);

    PSHFLFSOBJINFO pObjInfo;
    uint32_t cbBuffer;
    int vboxRC;

    Log(("VBOXSF: vbsfSetEndOfFile: New size = %RX64 (%p), pNewAllocationSize = %p\n",
         pNewFileSize->QuadPart, pNewFileSize, pNewAllocationSize));

    Assert(pVBoxFobx && pNetRootExtension && pDeviceExtension);

    cbBuffer = sizeof(SHFLFSOBJINFO);
    pObjInfo = (SHFLFSOBJINFO *)vbsfAllocNonPagedMem(cbBuffer);
    if (pObjInfo == NULL)
    {
        AssertFailed();
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(pObjInfo, cbBuffer);
    pObjInfo->cbObject = pNewFileSize->QuadPart;

    vboxRC = vboxCallFSInfo(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
                            SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)pObjInfo);

    Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo returned %Rrc\n",
         vboxRC));

    Status = VBoxErrorToNTStatus(vboxRC);
    if (Status == STATUS_SUCCESS)
    {
        Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo new allocation size = %RX64\n",
             pObjInfo->cbAllocated));

        /* Return new allocation size */
        pNewAllocationSize->QuadPart = pObjInfo->cbAllocated;
    }

    if (pObjInfo)
    {
        vbsfFreeNonPagedMem(pObjInfo);
    }

    Log(("VBOXSF: vbsfSetEndOfFile: Returned 0x%08X\n",
         Status));
    return Status;
}
Пример #3
0
NTSTATUS VBoxMRxLocks(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);

    PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
    uint32_t fu32Lock = 0;
    int vboxRC;

    Log(("VBOXSF: MRxLocks: Operation %d\n",
         LowIoContext->Operation));

    switch (LowIoContext->Operation)
    {
        default:
            AssertMsgFailed(("VBOXSF: MRxLocks: Unsupported lock/unlock type %d detected!\n",
                             LowIoContext->Operation));
            return STATUS_NOT_IMPLEMENTED;

        case LOWIO_OP_UNLOCK_MULTIPLE:
            /* @todo Remove multiple locks listed in LowIoContext.ParamsFor.Locks.LockList. */
            Log(("VBOXSF: MRxLocks: Unsupported LOWIO_OP_UNLOCK_MULTIPLE!\n",
                 LowIoContext->Operation));
            return STATUS_NOT_IMPLEMENTED;

        case LOWIO_OP_SHAREDLOCK:
            fu32Lock = SHFL_LOCK_SHARED | SHFL_LOCK_PARTIAL;
            break;

        case LOWIO_OP_EXCLUSIVELOCK:
            fu32Lock = SHFL_LOCK_EXCLUSIVE | SHFL_LOCK_PARTIAL;
            break;

        case LOWIO_OP_UNLOCK:
            fu32Lock = SHFL_LOCK_CANCEL | SHFL_LOCK_PARTIAL;
            break;
    }

    if (LowIoContext->ParamsFor.Locks.Flags & LOWIO_LOCKSFLAG_FAIL_IMMEDIATELY)
        fu32Lock |= SHFL_LOCK_NOWAIT;
    else
        fu32Lock |= SHFL_LOCK_WAIT;

    vboxRC = vboxCallLock(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
                          LowIoContext->ParamsFor.Locks.ByteOffset, LowIoContext->ParamsFor.Locks.Length, fu32Lock);

    Status = VBoxErrorToNTStatus(vboxRC);

    Log(("VBOXSF: MRxLocks: Returned 0x%08X\n", Status));
    return Status;
}
Пример #4
0
NTSTATUS VBoxMRxCloseSrvOpen(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);
    PMRX_SRV_OPEN pSrvOpen = capFobx->pSrvOpen;

    int vboxRC = 0;
    PUNICODE_STRING RemainingName = NULL;

    Log(("VBOXSF: MRxCloseSrvOpen: capFcb = %p, capFobx = %p, pVBoxFobx = %p, pSrvOpen = %p\n",
          capFcb, capFobx, pVBoxFobx, pSrvOpen));

    RemainingName = pSrvOpen->pAlreadyPrefixedName;

    Log(("VBOXSF: MRxCloseSrvOpen: Remaining name = %.*ls, Len = %d\n",
         RemainingName->Length / sizeof(WCHAR), RemainingName->Buffer, RemainingName->Length));

    if (NULL == pVBoxFobx)
    {
        return STATUS_INVALID_PARAMETER;
    }

    if (FlagOn(pSrvOpen->Flags, (SRVOPEN_FLAG_FILE_RENAMED | SRVOPEN_FLAG_FILE_DELETED)))
    {
        /* If we renamed or delete the file/dir, then it's already closed */
        Assert(pVBoxFobx->hFile == SHFL_HANDLE_NIL);
        Log(("VBOXSF: MRxCloseSrvOpen: File was renamed, handle 0x%RX64 ignore close.\n",
             pVBoxFobx->hFile));
        return STATUS_SUCCESS;
    }

    /* Close file */
    if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
    {
        vbsfCloseFileHandle(pDeviceExtension, pNetRootExtension, pVBoxFobx);
    }

    if (capFcb->FcbState & FCB_STATE_DELETE_ON_CLOSE)
    {
        Log(("VBOXSF: MRxCloseSrvOpen: Delete on close. Open count = %d\n",
             capFcb->OpenCount));

        /* Remove file or directory if delete action is pending. */
        if (capFcb->OpenCount == 0)
        {
            Status = vbsfRemove(RxContext);
        }
    }

    return Status;
}
Пример #5
0
NTSTATUS VBoxMRxCleanupFobx(IN PRX_CONTEXT RxContext)
{
    PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(RxContext->pFobx);

    Log(("VBOXSF: MRxCleanupFobx: pVBoxFobx = %p, Handle = 0x%RX64\n",
          pVBoxFobx, pVBoxFobx? pVBoxFobx->hFile: 0));

    if (NULL == pVBoxFobx)
    {
        return STATUS_INVALID_PARAMETER;
    }

    return STATUS_SUCCESS;
}
Пример #6
0
NTSTATUS VBoxMRxFlush (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);

    int vboxRC;

    Log(("VBOXSF: MRxFlush\n"));

    /* Do the actual flushing of file buffers */
    vboxRC = vboxCallFlush(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile);

    Status = VBoxErrorToNTStatus(vboxRC);

    Log(("VBOXSF: MRxFlush: Returned 0x%08X\n", Status));
    return Status;
}
Пример #7
0
static NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
{
    NTSTATUS Status = STATUS_SUCCESS;
    VBSFTRANSFERCTX ctx;

    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
    PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
    PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);

    PLOWIO_CONTEXT LowIoContext  = &RxContext->LowIoContext;

    PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
    uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;

    PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);

    int vboxRC;

    BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
    LONGLONG FileSize;

    RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);

    Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
         AsyncIo, capFcb->Header.FileSize.QuadPart));
    Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
         pbUserBuffer, BufferMdl));
    Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
         ByteCount, ByteOffset, FileSize));

    /* @todo allow to write 0 bytes. */
    if (   !BufferMdl
        || ByteCount == 0)
    {
        AssertFailed();
        return STATUS_INVALID_PARAMETER;
    }

    ctx.pClient = &pDeviceExtension->hgcmClient;
    ctx.pMap    = &pNetRootExtension->map;
    ctx.hFile   = pVBoxFobx->hFile;
    ctx.offset  = (uint64_t)ByteOffset;
    ctx.cbData  = ByteCount;
    ctx.pMdl    = BufferMdl;
    ctx.pBuffer = (uint8_t *)pbUserBuffer;
    ctx.fLocked = true;
    ctx.pfnTransferBuffer = vbsfTransferBufferWrite;
    ctx.pfnTransferPages = vbsfTransferPagesWrite;

    vboxRC = vbsfTransferCommon(&ctx);

    ByteCount = ctx.cbData;

    Status = VBoxErrorToNTStatus(vboxRC);

    if (Status != STATUS_SUCCESS)
    {
        /* Nothing written. */
        ByteCount = 0;
    }

    RxContext->InformationToReturn = ByteCount;

    Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
         Status, ByteCount));

    return Status;
}
Пример #8
0
static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
{
    NTSTATUS Status = STATUS_SUCCESS;
    VBSFTRANSFERCTX ctx;

    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
    PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
    PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);

    PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;

    PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
    uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;

    PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);

    int vboxRC;

    BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
    LONGLONG FileSize;

    RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);

    Log(("VBOXSF: vbsfReadInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
         AsyncIo, capFcb->Header.FileSize.QuadPart));
    Log(("VBOXSF: vbsfReadInternal: UserBuffer %p, BufferMdl %p\n",
         pbUserBuffer, BufferMdl));
    Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
         ByteCount, ByteOffset, FileSize));

    /* @todo check if this is necessary. */
#ifdef FCB_STATE_READCACHING_ENABLED    /* Correct spelling for Vista 6001 SDK. */
    if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHING_ENABLED))
#else
    if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHEING_ENABLED))
#endif
    {
        if (ByteOffset >= FileSize)
        {
            Log(("VBOXSF: vbsfReadInternal: EOF\n"));
            return STATUS_END_OF_FILE;
        }

        if (ByteCount > FileSize - ByteOffset)
            ByteCount = (ULONG)(FileSize - ByteOffset);
    }

    /* @todo read 0 bytes == always success? */
    if (   !BufferMdl
        || ByteCount == 0)
    {
        AssertFailed();
        return STATUS_INVALID_PARAMETER;
    }

    ctx.pClient = &pDeviceExtension->hgcmClient;
    ctx.pMap    = &pNetRootExtension->map;
    ctx.hFile   = pVBoxFobx->hFile;
    ctx.offset  = (uint64_t)ByteOffset;
    ctx.cbData  = ByteCount;
    ctx.pMdl    = BufferMdl;
    ctx.pBuffer = (uint8_t *)pbUserBuffer;
    ctx.fLocked = true;
    ctx.pfnTransferBuffer = vbsfTransferBufferRead;
    ctx.pfnTransferPages = vbsfTransferPagesRead;

    vboxRC = vbsfTransferCommon(&ctx);

    ByteCount = ctx.cbData;

    Status = VBoxErrorToNTStatus(vboxRC);

    if (Status != STATUS_SUCCESS)
    {
        /* Nothing read. */
        ByteCount = 0;
    }

    RxContext->InformationToReturn = ByteCount;

    Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
         Status, ByteCount));

    return Status;
}
Пример #9
0
NTSTATUS vbsfRename(IN PRX_CONTEXT RxContext,
                       IN FILE_INFORMATION_CLASS FileInformationClass,
                       IN PVOID pBuffer,
                       IN ULONG BufferLength)
{
    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);
    PMRX_SRV_OPEN pSrvOpen = capFobx->pSrvOpen;

    PFILE_RENAME_INFORMATION RenameInformation = (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
    PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME(pSrvOpen, capFcb);

    int vboxRC;
    PSHFLSTRING SrcPath = 0, DestPath = 0;
    ULONG ParsedPathSize, flags;

    Assert(FileInformationClass == FileRenameInformation);

    Log(("VBOXSF: vbsfRename: FileName = %.*ls\n",
         RenameInformation->FileNameLength / sizeof(WCHAR), &RenameInformation->FileName[0]));

    /* Must close the file before renaming it! */
    if (pVBoxFobx->hFile != SHFL_HANDLE_NIL)
    {
        vbsfCloseFileHandle(pDeviceExtension, pNetRootExtension, pVBoxFobx);
    }

    /* Mark it as renamed, so we do nothing during close */
    SetFlag(pSrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED);

    /* Calculate length required for destination path. */
    ParsedPathSize = sizeof(*DestPath) + (RenameInformation->FileNameLength + sizeof(WCHAR));

    Log(("VBOXSF: vbsfRename: ParsedPathSize = %d\n",
         ParsedPathSize));

    DestPath = (PSHFLSTRING)vbsfAllocNonPagedMem(ParsedPathSize);

    if (NULL == DestPath)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(DestPath, ParsedPathSize);
    ShflStringInitBuffer(DestPath, ParsedPathSize - sizeof(SHFLSTRING));

    Log(("VBOXSF: vbsfRename: Setting up destination path\n"));

    DestPath->u16Size = (USHORT)(RenameInformation->FileNameLength + sizeof(WCHAR));
    DestPath->u16Length = DestPath->u16Size - sizeof(WCHAR); /* without terminating null */
    RtlCopyMemory(DestPath->String.ucs2, RenameInformation->FileName, DestPath->u16Length);

    Log(("VBOXSF: vbsfRename: Destination path = %.*ls\n",
         DestPath->u16Length / sizeof(WCHAR), &DestPath->String.ucs2[0]));

    /* Calculate length required for source path */
    ParsedPathSize = sizeof(*DestPath) + (RemainingName->Length + sizeof(WCHAR));

    Log(("VBOXSF: vbsfRename: ParsedPathSize = %d\n", ParsedPathSize));

    SrcPath = (PSHFLSTRING)vbsfAllocNonPagedMem(ParsedPathSize);

    if (NULL == SrcPath)
    {
        vbsfFreeNonPagedMem(DestPath);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(SrcPath, ParsedPathSize);
    ShflStringInitBuffer(SrcPath, ParsedPathSize - sizeof(SHFLSTRING));

    Log(("VBOXSF: vbsfRename: Setting up source path\n"));

    SrcPath->u16Size = RemainingName->Length + sizeof(WCHAR);
    SrcPath->u16Length = SrcPath->u16Size - sizeof(WCHAR); /* without terminating null */
    RtlCopyMemory(SrcPath->String.ucs2, RemainingName->Buffer, SrcPath->u16Length);

    Log(("VBOXSF: vbsfRename: Source path = %.*ls\n",
         SrcPath->u16Length / sizeof(WCHAR), &SrcPath->String.ucs2[0]));

    /* Call host. */
    flags = pVBoxFobx->FileStandardInfo.Directory? SHFL_RENAME_DIR : SHFL_RENAME_FILE;
    if (RenameInformation->ReplaceIfExists)
    {
        flags |= SHFL_RENAME_REPLACE_IF_EXISTS;
    }

    Log(("VBOXSF: vbsfRename: Calling vboxCallRename\n"));
    vboxRC = vboxCallRename(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, SrcPath, DestPath, flags);

    vbsfFreeNonPagedMem(SrcPath);
    vbsfFreeNonPagedMem(DestPath);

    Status = VBoxErrorToNTStatus(vboxRC);
    if (vboxRC != VINF_SUCCESS)
    {
        Log(("VBOXSF: vbsfRename: vboxCallRename failed with %Rrc\n",
             vboxRC));
    }

    Log(("VBOXSF: vbsfRename: Returned 0x%08X\n",
         Status));
    return Status;
}
Пример #10
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;
}
Пример #11
0
NTSTATUS VBoxMRxCreate(IN OUT PRX_CONTEXT RxContext)
{
    NTSTATUS Status = STATUS_SUCCESS;

    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_NET_ROOT pNetRoot = capFcb->pNetRoot;
    PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
    PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);

    FILE_BASIC_INFORMATION FileBasicInfo;
    FILE_STANDARD_INFORMATION FileStandardInfo;

    ULONG CreateAction = FILE_CREATED;
    SHFLHANDLE Handle = SHFL_HANDLE_NIL;
    PMRX_VBOX_FOBX pVBoxFobx;

    Log(("VBOXSF: MRxCreate: name ptr %p length=%d, SrvOpen->Flags 0x%08X\n",
         RemainingName, RemainingName->Length, SrvOpen->Flags));

    /* Disable FastIO. It causes a verifier bugcheck. */
#ifdef SRVOPEN_FLAG_DONTUSE_READ_CACHING
    SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_DONTUSE_READ_CACHING | SRVOPEN_FLAG_DONTUSE_WRITE_CACHING);
#else
    SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_DONTUSE_READ_CACHEING | SRVOPEN_FLAG_DONTUSE_WRITE_CACHEING);
#endif

    if (RemainingName->Length)
    {
        Log(("VBOXSF: MRxCreate: Attempt to open %.*ls\n",
             RemainingName->Length/sizeof(WCHAR), RemainingName->Buffer));
    }
    else
    {
        if (FlagOn(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH))
        {
            Log(("VBOXSF: MRxCreate: Empty name -> Only backslash used\n"));
            RemainingName = &UnicodeBackslash;
        }
    }

    if (   pNetRoot->Type != NET_ROOT_WILD
        && pNetRoot->Type != NET_ROOT_DISK)
    {
        Log(("VBOXSF: MRxCreate: netroot type %d not supported\n",
             pNetRoot->Type));
        Status = STATUS_NOT_IMPLEMENTED;
        goto Exit;
    }

    FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;

    Status = vbsfProcessCreate(RxContext,
                               RemainingName,
                               &FileBasicInfo,
                               &FileStandardInfo,
                               RxContext->Create.EaBuffer,
                               RxContext->Create.EaLength,
                               &CreateAction,
                               &Handle);

    if (Status != STATUS_SUCCESS)
    {
        Log(("VBOXSF: MRxCreate: vbsfProcessCreate failed 0x%08X\n",
             Status));
        goto Exit;
    }

    Log(("VBOXSF: MRxCreate: EOF is 0x%RX64 AllocSize is 0x%RX64\n",
         FileStandardInfo.EndOfFile.QuadPart, FileStandardInfo.AllocationSize.QuadPart));

    RxContext->pFobx = RxCreateNetFobx(RxContext, SrvOpen);
    if (RxContext->pFobx == NULL)
    {
        Log(("VBOXSF: MRxCreate: RxCreateNetFobx failed\n"));
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    Log(("VBOXSF: MRxCreate: CreateAction = 0x%08X\n",
         CreateAction));

    RxContext->Create.ReturnedCreateInformation = CreateAction;

    if (capFcb->OpenCount == 0)
    {
        FCB_INIT_PACKET InitPacket;
        RxFormInitPacket(InitPacket,
                         &FileBasicInfo.FileAttributes,
                         &FileStandardInfo.NumberOfLinks,
                         &FileBasicInfo.CreationTime,
                         &FileBasicInfo.LastAccessTime,
                         &FileBasicInfo.LastWriteTime,
                         &FileBasicInfo.ChangeTime,
                         &FileStandardInfo.AllocationSize,
                         &FileStandardInfo.EndOfFile,
                         &FileStandardInfo.EndOfFile);
        RxFinishFcbInitialization(capFcb, RDBSS_STORAGE_NTC(FileTypeFile), &InitPacket);
    }

    SrvOpen->BufferingFlags = 0;

    RxContext->pFobx->OffsetOfNextEaToReturn = 1;

    pVBoxFobx = VBoxMRxGetFileObjectExtension(RxContext->pFobx);

    Log(("VBOXSF: MRxCreate: VBoxFobx = %p\n",
         pVBoxFobx));

    if (!pVBoxFobx)
    {
        Log(("VBOXSF: MRxCreate: no VBoxFobx!\n"));
        AssertFailed();
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    Log(("VBOXSF: MRxCreate: FileBasicInformation: CreationTime   %RX64\n", FileBasicInfo.CreationTime.QuadPart));
    Log(("VBOXSF: MRxCreate: FileBasicInformation: LastAccessTime %RX64\n", FileBasicInfo.LastAccessTime.QuadPart));
    Log(("VBOXSF: MRxCreate: FileBasicInformation: LastWriteTime  %RX64\n", FileBasicInfo.LastWriteTime.QuadPart));
    Log(("VBOXSF: MRxCreate: FileBasicInformation: ChangeTime     %RX64\n", FileBasicInfo.ChangeTime.QuadPart));
    Log(("VBOXSF: MRxCreate: FileBasicInformation: FileAttributes %RX32\n", FileBasicInfo.FileAttributes));

    pVBoxFobx->hFile = Handle;
    pVBoxFobx->pSrvCall = RxContext->Create.pSrvCall;
    pVBoxFobx->FileStandardInfo = FileStandardInfo;
    pVBoxFobx->FileBasicInfo = FileBasicInfo;
    pVBoxFobx->fKeepCreationTime = FALSE;
    pVBoxFobx->fKeepLastAccessTime = FALSE;
    pVBoxFobx->fKeepLastWriteTime = FALSE;
    pVBoxFobx->fKeepChangeTime = FALSE;
    pVBoxFobx->SetFileInfoOnCloseFlags = 0;

    if (!RxIsFcbAcquiredExclusive(capFcb))
    {
        RxAcquireExclusiveFcbResourceInMRx(capFcb);
    }

    Log(("VBOXSF: MRxCreate: NetRoot is %p, Fcb is %p, SrvOpen is %p, Fobx is %p\n",
         pNetRoot, capFcb, SrvOpen, RxContext->pFobx));
    Log(("VBOXSF: MRxCreate: return 0x%08X\n",
         Status));

Exit:
    return Status;
}