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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }