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 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; }
NTSTATUS VBoxMRxCreateVNetRoot(IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext) { NTSTATUS Status; PMRX_V_NET_ROOT pVNetRoot = (PMRX_V_NET_ROOT)pCreateNetRootContext->pVNetRoot; PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(pCreateNetRootContext->RxContext); PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(pVNetRoot->pNetRoot); PMRX_NET_ROOT pNetRoot = pVNetRoot->pNetRoot; PMRX_SRV_CALL pSrvCall = pNetRoot->pSrvCall; BOOLEAN fInitializeNetRoot = FALSE; Log(("VBOXSF: MRxCreateVNetRoot: pNetRoot = %p, pNetRootExtension = %p, name = [%.*ls]\n", pNetRoot, pNetRootExtension, pNetRoot->pNetRootName->Length / sizeof(WCHAR), pNetRoot->pNetRootName->Buffer)); /* IMPORTANT: * * This function must always call 'pCreateNetRootContext->Callback(pCreateNetRootContext)' before * returning and then return STATUS_PENDING. Otherwise Win64 will hang. */ if (pNetRoot->Type == NET_ROOT_PIPE) { /* VBoxSF claims everything which starts with '\vboxsrv'. * * So sometimes the system tries to open \vboxsrv\ipc$ pipe for DFS * and fails the application call if an unexpected code is returned. * * According to MSDN: The Windows client returns STATUS_MORE_PROCESSING_REQUIRED to the calling * application to indicate that the path does not correspond to a DFS Namespace. */ pVNetRoot->Context = NULL; if (pNetRoot->pNetRootName->Length >= 13 * sizeof (WCHAR)) /* Number of bytes in '\vboxsrv\ipc$' unicode string. */ { const WCHAR *Suffix = &pNetRoot->pNetRootName->Buffer[8]; /* Number of chars in '\vboxsrv' */ if ( Suffix[0] == L'\\' && (Suffix[1] == L'I' || Suffix[1] == L'i') && (Suffix[2] == L'P' || Suffix[2] == L'p') && (Suffix[3] == L'C' || Suffix[3] == L'c') && Suffix[4] == L'$' ) { if ( pNetRoot->pNetRootName->Length == 13 * sizeof (WCHAR) || (Suffix[5] == L'\\' || Suffix[5] == 0) ) { /* It is '\vboxsrv\IPC$[\*]'. */ Log(("VBOXSF: MRxCreateVNetRoot: IPC$\n")); Status = STATUS_MORE_PROCESSING_REQUIRED; goto l_Exit; } } } /* Fail all other pipe open requests. */ Log(("VBOXSF: MRxCreateVNetRoot: Pipe open not supported!\n")); Status = STATUS_NOT_SUPPORTED; goto l_Exit; } else if (pNetRoot->Type == NET_ROOT_MAILSLOT) { Log(("VBOXSF: MRxCreateVNetRoot: Mailslot open not supported!\n")); pVNetRoot->Context = NULL; Status = STATUS_NOT_SUPPORTED; goto l_Exit; } if (!pNetRoot->Context) { /* MRxNetRootSize is not zero in VBoxSF, so it is expected * that the Context, which is NetRootExtension, is already allocated. */ Log(("VBOXSF: MRxCreateVNetRoot: NULL netroot context\n")); pVNetRoot->Context = NULL; Status = STATUS_NOT_SUPPORTED; goto l_Exit; } /* Detect an already initialized NetRoot. * pNetRootExtension is actually the pNetRoot->Context and it is not NULL. */ fInitializeNetRoot = (pNetRootExtension->phgcmClient == NULL); Status = STATUS_SUCCESS; if (fInitializeNetRoot) { PWCHAR pRootName; ULONG RootNameLength; int vboxRC; PSHFLSTRING ParsedPath = 0; Log(("VBOXSF: MRxCreateVNetRoot: initialize NET_ROOT\n")); pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD; RootNameLength = pNetRoot->pNetRootName->Length - pSrvCall->pSrvCallName->Length; if (RootNameLength < sizeof(WCHAR)) { /* Refuse a netroot path with an empty shared folder name */ Log(("VBOXSF: MRxCreateVNetRoot: Empty shared folder name!\n")); pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_ERROR; Status = STATUS_BAD_NETWORK_NAME; goto l_Exit; } RootNameLength -= sizeof(WCHAR); /* Remove leading backslash. */ pRootName = (PWCHAR)(pNetRoot->pNetRootName->Buffer + (pSrvCall->pSrvCallName->Length / sizeof(WCHAR))); pRootName++; /* Remove leading backslash. */ /* Strip the trailing \0. Sometimes there is one, sometimes not... */ if ( RootNameLength >= sizeof(WCHAR) && pRootName[RootNameLength / sizeof(WCHAR) - 1] == 0) RootNameLength -= sizeof(WCHAR); if (!pNetRootExtension->phgcmClient) { Log(("VBOXSF: MRxCreateVNetRoot: Initialize netroot length = %d, name = %.*ls\n", RootNameLength, RootNameLength / sizeof(WCHAR), pRootName)); Status = vbsfShflStringFromUnicodeAlloc(&ParsedPath, pRootName, (uint16_t)RootNameLength); if (Status != STATUS_SUCCESS) { goto l_Exit; } vboxRC = VbglR0SfMapFolder(&pDeviceExtension->hgcmClient, ParsedPath, &pNetRootExtension->map); vbsfFreeNonPagedMem(ParsedPath); if (vboxRC != VINF_SUCCESS) { Log(("VBOXSF: MRxCreateVNetRoot: VbglR0SfMapFolder failed with %d\n", vboxRC)); Status = STATUS_BAD_NETWORK_NAME; } else { Status = STATUS_SUCCESS; pNetRootExtension->phgcmClient = &pDeviceExtension->hgcmClient; } } } else Log(("VBOXSF: MRxCreateVNetRoot: Creating V_NET_ROOT on existing NET_ROOT!\n")); vbsfUpdateNetRoot(pNetRoot); l_Exit: if (Status != STATUS_PENDING) { Log(("VBOXSF: MRxCreateVNetRoot: Returning 0x%08X\n", Status)); pCreateNetRootContext->VirtualNetRootStatus = Status; if (fInitializeNetRoot) pCreateNetRootContext->NetRootStatus = Status; else pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS; /* Inform RDBSS. */ pCreateNetRootContext->Callback(pCreateNetRootContext); /* RDBSS expects this. */ Status = STATUS_PENDING; } Log(("VBOXSF: MRxCreateVNetRoot: Returned STATUS_PENDING\n")); 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; }
static NTSTATUS vbsfProcessCreate(PRX_CONTEXT RxContext, PUNICODE_STRING RemainingName, FILE_BASIC_INFORMATION *pFileBasicInfo, FILE_STANDARD_INFORMATION *pFileStandardInfo, PVOID EaBuffer, ULONG EaLength, ULONG *pulCreateAction, SHFLHANDLE *pHandle) { NTSTATUS Status = STATUS_SUCCESS; RxCaptureFcb; PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext); PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot); int vboxRC = VINF_SUCCESS; /* Various boolean flags. */ struct { ULONG CreateDirectory :1; ULONG OpenDirectory :1; ULONG DirectoryFile :1; ULONG NonDirectoryFile :1; ULONG DeleteOnClose :1; ULONG TemporaryFile :1; } bf; ACCESS_MASK DesiredAccess; ULONG Options; UCHAR FileAttributes; ULONG ShareAccess; ULONG CreateDisposition; SHFLCREATEPARMS *pCreateParms = NULL; if (EaLength) { Log(("VBOXSF: vbsfProcessCreate: Unsupported: extended attributes!\n")); Status = STATUS_NOT_SUPPORTED; goto failure; } if (BooleanFlagOn(capFcb->FcbState, FCB_STATE_PAGING_FILE)) { Log(("VBOXSF: vbsfProcessCreate: Unsupported: paging file!\n")); Status = STATUS_NOT_IMPLEMENTED; goto failure; } Log(("VBOXSF: vbsfProcessCreate: FileAttributes = 0x%08x\n", RxContext->Create.NtCreateParameters.FileAttributes)); Log(("VBOXSF: vbsfProcessCreate: CreateOptions = 0x%08x\n", RxContext->Create.NtCreateParameters.CreateOptions)); RtlZeroMemory (&bf, sizeof (bf)); DesiredAccess = RxContext->Create.NtCreateParameters.DesiredAccess; Options = RxContext->Create.NtCreateParameters.CreateOptions & FILE_VALID_OPTION_FLAGS; FileAttributes = (UCHAR)(RxContext->Create.NtCreateParameters.FileAttributes & ~FILE_ATTRIBUTE_NORMAL); ShareAccess = RxContext->Create.NtCreateParameters.ShareAccess; /* We do not support opens by file ids. */ if (FlagOn(Options, FILE_OPEN_BY_FILE_ID)) { Log(("VBOXSF: vbsfProcessCreate: Unsupported: file open by id!\n")); Status = STATUS_NOT_IMPLEMENTED; goto failure; } /* Mask out unsupported attribute bits. */ FileAttributes &= (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE); bf.DirectoryFile = BooleanFlagOn(Options, FILE_DIRECTORY_FILE); bf.NonDirectoryFile = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE); bf.DeleteOnClose = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE); if (bf.DeleteOnClose) Log(("VBOXSF: vbsfProcessCreate: Delete on close!\n")); CreateDisposition = RxContext->Create.NtCreateParameters.Disposition; bf.CreateDirectory = (BOOLEAN)(bf.DirectoryFile && ((CreateDisposition == FILE_CREATE) || (CreateDisposition == FILE_OPEN_IF))); bf.OpenDirectory = (BOOLEAN)(bf.DirectoryFile && ((CreateDisposition == FILE_OPEN) || (CreateDisposition == FILE_OPEN_IF))); bf.TemporaryFile = BooleanFlagOn(RxContext->Create.NtCreateParameters.FileAttributes, FILE_ATTRIBUTE_TEMPORARY); if (FlagOn(capFcb->FcbState, FCB_STATE_TEMPORARY)) bf.TemporaryFile = TRUE; Log(("VBOXSF: vbsfProcessCreate: bf.TemporaryFile %d, bf.CreateDirectory %d, bf.DirectoryFile = %d\n", (ULONG)bf.TemporaryFile, (ULONG)bf.CreateDirectory, (ULONG)bf.DirectoryFile)); /* Check consistency in specified flags. */ if (bf.TemporaryFile && bf.CreateDirectory) /* Directories with temporary flag set are not allowed! */ { Log(("VBOXSF: vbsfProcessCreate: Not allowed: Temporary directories!\n")); Status = STATUS_INVALID_PARAMETER; goto failure; } if (bf.DirectoryFile && bf.NonDirectoryFile) { Log(("VBOXSF: vbsfProcessCreate: Unsupported combination: dir && !dir\n")); Status = STATUS_INVALID_PARAMETER; goto failure; } /* Initialize create parameters. */ pCreateParms = (SHFLCREATEPARMS *)vbsfAllocNonPagedMem(sizeof(SHFLCREATEPARMS)); if (!pCreateParms) { Status = STATUS_INSUFFICIENT_RESOURCES; goto failure; } RtlZeroMemory(pCreateParms, sizeof (SHFLCREATEPARMS)); pCreateParms->Handle = SHFL_HANDLE_NIL; pCreateParms->Result = SHFL_NO_RESULT; if (bf.DirectoryFile) { if (CreateDisposition != FILE_CREATE && CreateDisposition != FILE_OPEN && CreateDisposition != FILE_OPEN_IF) { Log(("VBOXSF: vbsfProcessCreate: Invalid disposition 0x%08X for directory!\n", CreateDisposition)); Status = STATUS_INVALID_PARAMETER; goto failure; } pCreateParms->CreateFlags |= SHFL_CF_DIRECTORY; } Log(("VBOXSF: vbsfProcessCreate: CreateDisposition = 0x%08X\n", CreateDisposition)); switch (CreateDisposition) { case FILE_SUPERSEDE: pCreateParms->CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n")); break; case FILE_OPEN: pCreateParms->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n")); break; case FILE_CREATE: pCreateParms->CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n")); break; case FILE_OPEN_IF: pCreateParms->CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n")); break; case FILE_OVERWRITE: pCreateParms->CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n")); break; case FILE_OVERWRITE_IF: pCreateParms->CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW; Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n")); break; default: Log(("VBOXSF: vbsfProcessCreate: Unexpected create disposition: 0x%08X\n", CreateDisposition)); Status = STATUS_INVALID_PARAMETER; goto failure; } Log(("VBOXSF: vbsfProcessCreate: DesiredAccess = 0x%08X\n", DesiredAccess)); Log(("VBOXSF: vbsfProcessCreate: ShareAccess = 0x%08X\n", ShareAccess)); if (DesiredAccess & FILE_READ_DATA) { Log(("VBOXSF: vbsfProcessCreate: FILE_READ_DATA\n")); pCreateParms->CreateFlags |= SHFL_CF_ACCESS_READ; } if (DesiredAccess & FILE_WRITE_DATA) { Log(("VBOXSF: vbsfProcessCreate: FILE_WRITE_DATA\n")); /* FILE_WRITE_DATA means write access regardless of FILE_APPEND_DATA bit. */ pCreateParms->CreateFlags |= SHFL_CF_ACCESS_WRITE; } else if (DesiredAccess & FILE_APPEND_DATA) { Log(("VBOXSF: vbsfProcessCreate: FILE_APPEND_DATA\n")); /* FILE_APPEND_DATA without FILE_WRITE_DATA means append only mode. * * Both write and append access flags are required for shared folders, * as on Windows FILE_APPEND_DATA implies write access. */ pCreateParms->CreateFlags |= SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_APPEND; } if (DesiredAccess & FILE_READ_ATTRIBUTES) pCreateParms->CreateFlags |= SHFL_CF_ACCESS_ATTR_READ; if (DesiredAccess & FILE_WRITE_ATTRIBUTES) pCreateParms->CreateFlags |= SHFL_CF_ACCESS_ATTR_WRITE; if (ShareAccess & (FILE_SHARE_READ | FILE_SHARE_WRITE)) pCreateParms->CreateFlags |= SHFL_CF_ACCESS_DENYNONE; else if (ShareAccess & FILE_SHARE_READ) pCreateParms->CreateFlags |= SHFL_CF_ACCESS_DENYWRITE; else if (ShareAccess & FILE_SHARE_WRITE) pCreateParms->CreateFlags |= SHFL_CF_ACCESS_DENYREAD; else pCreateParms->CreateFlags |= SHFL_CF_ACCESS_DENYALL; /* Set initial allocation size. */ pCreateParms->Info.cbObject = RxContext->Create.NtCreateParameters.AllocationSize.QuadPart; if (FileAttributes == 0) FileAttributes = FILE_ATTRIBUTE_NORMAL; pCreateParms->Info.Attr.fMode = NTToVBoxFileAttributes(FileAttributes); { PSHFLSTRING ParsedPath; ULONG ParsedPathSize; /* Calculate length required for parsed path. */ ParsedPathSize = sizeof(*ParsedPath) + (RemainingName->Length + sizeof(WCHAR)); Log(("VBOXSF: vbsfProcessCreate: ParsedPathSize = %d\n", ParsedPathSize)); ParsedPath = (PSHFLSTRING)vbsfAllocNonPagedMem(ParsedPathSize); if (ParsedPath == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto failure; } ShflStringInitBuffer(ParsedPath, ParsedPathSize - sizeof(SHFLSTRING)); ParsedPath->u16Size = RemainingName->Length + sizeof(WCHAR); ParsedPath->u16Length = ParsedPath->u16Size - sizeof(WCHAR); /* without terminating null */ RtlCopyMemory (ParsedPath->String.ucs2, RemainingName->Buffer, ParsedPath->u16Length); Log(("VBOXSF: ParsedPath: %.*ls\n", ParsedPath->u16Length / sizeof(WCHAR), ParsedPath->String.ucs2)); /* Call host. */ Log(("VBOXSF: vbsfProcessCreate: vboxCallCreate called.\n")); vboxRC = vboxCallCreate(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, ParsedPath, pCreateParms); vbsfFreeNonPagedMem(ParsedPath); } Log(("VBOXSF: vbsfProcessCreate: vboxCallCreate returns vboxRC = %Rrc, Result = 0x%x\n", vboxRC, pCreateParms->Result)); if (RT_FAILURE(vboxRC)) { /* Map some VBoxRC to STATUS codes expected by the system. */ switch (vboxRC) { case VERR_ALREADY_EXISTS: { *pulCreateAction = FILE_EXISTS; Status = STATUS_OBJECT_NAME_COLLISION; goto failure; } break; /* On POSIX systems, the "mkdir" command returns VERR_FILE_NOT_FOUND when doing a recursive directory create. Handle this case. */ case VERR_FILE_NOT_FOUND: { pCreateParms->Result = SHFL_PATH_NOT_FOUND; } break; default: { *pulCreateAction = FILE_DOES_NOT_EXIST; Status = VBoxErrorToNTStatus(vboxRC); goto failure; } break; } } /* * The request succeeded. Analyze host response, */ switch (pCreateParms->Result) { case SHFL_PATH_NOT_FOUND: { /* Path to object does not exist. */ Log(("VBOXSF: vbsfProcessCreate: Path not found\n")); *pulCreateAction = FILE_DOES_NOT_EXIST; Status = STATUS_OBJECT_PATH_NOT_FOUND; goto failure; } case SHFL_FILE_NOT_FOUND: { Log(("VBOXSF: vbsfProcessCreate: File not found\n")); *pulCreateAction = FILE_DOES_NOT_EXIST; if (pCreateParms->Handle == SHFL_HANDLE_NIL) { Status = STATUS_OBJECT_NAME_NOT_FOUND; goto failure; } Log(("VBOXSF: vbsfProcessCreate: File not found but have a handle!\n")); Status = STATUS_UNSUCCESSFUL; goto failure; break; } case SHFL_FILE_EXISTS: { Log(("VBOXSF: vbsfProcessCreate: File exists, Handle = 0x%RX64\n", pCreateParms->Handle)); if (pCreateParms->Handle == SHFL_HANDLE_NIL) { *pulCreateAction = FILE_EXISTS; if (CreateDisposition == FILE_CREATE) { /* File was not opened because we requested a create. */ Status = STATUS_OBJECT_NAME_COLLISION; goto failure; } /* Actually we should not go here, unless we have no rights to open the object. */ Log(("VBOXSF: vbsfProcessCreate: Existing file was not opened!\n")); Status = STATUS_ACCESS_DENIED; goto failure; } *pulCreateAction = FILE_OPENED; /* Existing file was opened. Go check flags and create FCB. */ break; } case SHFL_FILE_CREATED: { /* A new file was created. */ Assert(pCreateParms->Handle != SHFL_HANDLE_NIL); *pulCreateAction = FILE_CREATED; /* Go check flags and create FCB. */ break; } case SHFL_FILE_REPLACED: { /* Existing file was replaced or overwriting. */ Assert(pCreateParms->Handle != SHFL_HANDLE_NIL); if (CreateDisposition == FILE_SUPERSEDE) { *pulCreateAction = FILE_SUPERSEDED; } else { *pulCreateAction = FILE_OVERWRITTEN; } /* Go check flags and create FCB. */ break; } default: { Log(("VBOXSF: vbsfProcessCreate: Invalid CreateResult from host (0x%08X)\n", pCreateParms->Result)); *pulCreateAction = FILE_DOES_NOT_EXIST; Status = STATUS_OBJECT_PATH_NOT_FOUND; goto failure; } } /* Check flags. */ if (bf.NonDirectoryFile && FlagOn(pCreateParms->Info.Attr.fMode, RTFS_DOS_DIRECTORY)) { /* Caller wanted only a file, but the object is a directory. */ Log(("VBOXSF: vbsfProcessCreate: File is a directory!\n")); Status = STATUS_FILE_IS_A_DIRECTORY; goto failure; } if (bf.DirectoryFile && !FlagOn(pCreateParms->Info.Attr.fMode, RTFS_DOS_DIRECTORY)) { /* Caller wanted only a directory, but the object is not a directory. */ Log(("VBOXSF: vbsfProcessCreate: File is not a directory!\n")); Status = STATUS_NOT_A_DIRECTORY; goto failure; } *pHandle = pCreateParms->Handle; /* Translate attributes */ pFileBasicInfo->FileAttributes = VBoxToNTFileAttributes(pCreateParms->Info.Attr.fMode); /* Translate file times */ pFileBasicInfo->CreationTime.QuadPart = RTTimeSpecGetNtTime(&pCreateParms->Info.BirthTime); /* ridiculous name */ pFileBasicInfo->LastAccessTime.QuadPart = RTTimeSpecGetNtTime(&pCreateParms->Info.AccessTime); pFileBasicInfo->LastWriteTime.QuadPart = RTTimeSpecGetNtTime(&pCreateParms->Info.ModificationTime); pFileBasicInfo->ChangeTime.QuadPart = RTTimeSpecGetNtTime(&pCreateParms->Info.ChangeTime); if (!FlagOn(pCreateParms->Info.Attr.fMode, RTFS_DOS_DIRECTORY)) { pFileStandardInfo->AllocationSize.QuadPart = pCreateParms->Info.cbAllocated; pFileStandardInfo->EndOfFile.QuadPart = pCreateParms->Info.cbObject; pFileStandardInfo->Directory = FALSE; Log(("VBOXSF: vbsfProcessCreate: AllocationSize = 0x%RX64, EndOfFile = 0x%RX64\n", pCreateParms->Info.cbAllocated, pCreateParms->Info.cbObject)); } else { pFileStandardInfo->AllocationSize.QuadPart = 0; pFileStandardInfo->EndOfFile.QuadPart = 0; pFileStandardInfo->Directory = TRUE; } pFileStandardInfo->NumberOfLinks = 0; pFileStandardInfo->DeletePending = FALSE; vbsfFreeNonPagedMem(pCreateParms); return Status; failure: Log(("VBOXSF: vbsfProcessCreate: Returned with status = 0x%08X\n", Status)); if (pCreateParms && pCreateParms->Handle != SHFL_HANDLE_NIL) { vboxCallClose(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pCreateParms->Handle); *pHandle = SHFL_HANDLE_NIL; } if (pCreateParms) { vbsfFreeNonPagedMem(pCreateParms); } return Status; }