summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/WINNT/SharedFolders
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/WINNT/SharedFolders
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/WINNT/SharedFolders')
-rw-r--r--src/VBox/Additions/WINNT/SharedFolders/driver/VBoxSF.inf2
-rw-r--r--src/VBox/Additions/WINNT/SharedFolders/driver/file.c248
-rw-r--r--src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c106
-rw-r--r--src/VBox/Additions/WINNT/SharedFolders/np/vboxmrxnp.cpp8
4 files changed, 331 insertions, 33 deletions
diff --git a/src/VBox/Additions/WINNT/SharedFolders/driver/VBoxSF.inf b/src/VBox/Additions/WINNT/SharedFolders/driver/VBoxSF.inf
index a178c456..f93d7732 100644
--- a/src/VBox/Additions/WINNT/SharedFolders/driver/VBoxSF.inf
+++ b/src/VBox/Additions/WINNT/SharedFolders/driver/VBoxSF.inf
@@ -1,7 +1,7 @@
;
; INF file for installing the VirtualBox Windows guest driver
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; Copyright (C) 2006-2012 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/SharedFolders/driver/file.c b/src/VBox/Additions/WINNT/SharedFolders/driver/file.c
index f8101cb5..ba39cb3f 100644
--- a/src/VBox/Additions/WINNT/SharedFolders/driver/file.c
+++ b/src/VBox/Additions/WINNT/SharedFolders/driver/file.c
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -19,10 +19,219 @@
#include "vbsf.h"
#include <iprt/fs.h>
+#include <iprt/mem.h>
+
+
+/* How much data to transfer in one HGCM request. */
+#define VBSF_MAX_READ_WRITE_PAGES 256
+
+
+typedef int FNVBSFTRANSFERBUFFER(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint8_t *pBuffer, bool fLocked);
+typedef FNVBSFTRANSFERBUFFER *PFNVBSFTRANSFERBUFFER;
+
+typedef int FNVBSFTRANSFERPAGES(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
+typedef FNVBSFTRANSFERPAGES *PFNVBSFTRANSFERPAGES;
+
+
+static int vbsfTransferBufferRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint8_t *pBuffer, bool fLocked)
+{
+ return vboxCallRead(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
+}
+
+static int vbsfTransferBufferWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint8_t *pBuffer, bool fLocked)
+{
+ return vboxCallWrite(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
+}
+
+static int vbsfTransferPagesRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
+{
+ return VbglR0SharedFolderReadPageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
+}
+
+static int vbsfTransferPagesWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
+ uint64_t offset, uint32_t *pcbBuffer,
+ uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
+{
+ return VbglR0SharedFolderWritePageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
+}
+
+
+typedef struct VBSFTRANSFERCTX
+{
+ PVBSFCLIENT pClient;
+ PVBSFMAP pMap;
+ SHFLHANDLE hFile;
+ uint64_t offset;
+ uint32_t cbData;
+
+ PMDL pMdl;
+ uint8_t *pBuffer;
+ bool fLocked;
+
+ PFNVBSFTRANSFERBUFFER pfnTransferBuffer;
+ PFNVBSFTRANSFERPAGES pfnTransferPages;
+} VBSFTRANSFERCTX;
+
+
+static int vbsfTransferCommon(VBSFTRANSFERCTX *pCtx)
+{
+ int rc = VINF_SUCCESS;
+ BOOLEAN fProcessed = FALSE;
+
+ uint32_t cbTransferred = 0;
+
+ uint32_t cbToTransfer;
+ uint32_t cbIO;
+
+ if (VbglR0CanUsePhysPageList())
+ {
+ ULONG offFirstPage = MmGetMdlByteOffset(pCtx->pMdl);
+ ULONG cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pCtx->pMdl), pCtx->cbData);
+ ULONG cPagesToTransfer = RT_MIN(cPages, VBSF_MAX_READ_WRITE_PAGES);
+ RTGCPHYS64 *paPages = (RTGCPHYS64 *)RTMemTmpAlloc(cPagesToTransfer * sizeof(RTGCPHYS64));
+
+ Log(("VBOXSF: vbsfTransferCommon: using page list: %d pages, offset 0x%03X\n", cPages, offFirstPage));
+
+ if (paPages)
+ {
+ PPFN_NUMBER paPfns = MmGetMdlPfnArray(pCtx->pMdl);
+ ULONG cPagesTransferred = 0;
+ cbTransferred = 0;
+
+ while (cPagesToTransfer != 0)
+ {
+ ULONG iPage;
+ cbToTransfer = cPagesToTransfer * PAGE_SIZE - offFirstPage;
+
+ if (cbToTransfer > pCtx->cbData - cbTransferred)
+ {
+ cbToTransfer = pCtx->cbData - cbTransferred;
+ }
+
+ if (cbToTransfer == 0)
+ {
+ /* Nothing to transfer. */
+ break;
+ }
+
+ cbIO = cbToTransfer;
+
+ Log(("VBOXSF: vbsfTransferCommon: transferring %d pages at %d; %d bytes at %d\n",
+ cPagesToTransfer, cPagesTransferred, cbToTransfer, cbTransferred));
+
+ for (iPage = 0; iPage < cPagesToTransfer; iPage++)
+ {
+ paPages[iPage] = (RTGCPHYS64)paPfns[iPage + cPagesTransferred] << PAGE_SHIFT;
+ }
+
+ rc = pCtx->pfnTransferPages(pCtx->pClient, pCtx->pMap, pCtx->hFile,
+ pCtx->offset + cbTransferred, &cbIO,
+ (uint16_t)offFirstPage, (uint16_t)cPagesToTransfer, paPages);
+ if (RT_FAILURE(rc))
+ {
+ Log(("VBOXSF: vbsfTransferCommon: pfnTransferPages %Rrc, cbTransferred %d\n", rc, cbTransferred));
+
+ /* If some data was transferred, then it is no error. */
+ if (cbTransferred > 0)
+ {
+ rc = VINF_SUCCESS;
+ }
+
+ break;
+ }
+
+ cbTransferred += cbIO;
+
+ if (cbToTransfer < cbIO)
+ {
+ /* Transferred less than requested, do not continue with the possibly remaining data. */
+ break;
+ }
+
+ cPagesTransferred += cPagesToTransfer;
+ offFirstPage = 0;
+
+ cPagesToTransfer = cPages - cPagesTransferred;
+ if (cPagesToTransfer > VBSF_MAX_READ_WRITE_PAGES)
+ {
+ cPagesToTransfer = VBSF_MAX_READ_WRITE_PAGES;
+ }
+ }
+
+ RTMemTmpFree(paPages);
+
+ fProcessed = TRUE;
+ }
+ }
+
+ if (fProcessed != TRUE)
+ {
+ /* Split large transfers. */
+ cbTransferred = 0;
+ cbToTransfer = RT_MIN(pCtx->cbData, VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE);
+
+ /* Page list not supported or a fallback. */
+ Log(("VBOXSF: vbsfTransferCommon: using linear address\n"));
+
+ while (cbToTransfer != 0)
+ {
+ cbIO = cbToTransfer;
+
+ Log(("VBOXSF: vbsfTransferCommon: transferring %d bytes at %d\n",
+ cbToTransfer, cbTransferred));
+
+ rc = pCtx->pfnTransferBuffer(pCtx->pClient, pCtx->pMap, pCtx->hFile,
+ pCtx->offset + cbTransferred, &cbIO,
+ pCtx->pBuffer + cbTransferred, true /* locked */);
+
+ if (RT_FAILURE(rc))
+ {
+ Log(("VBOXSF: vbsfTransferCommon: pfnTransferBuffer %Rrc, cbTransferred %d\n", rc, cbTransferred));
+
+ /* If some data was transferred, then it is no error. */
+ if (cbTransferred > 0)
+ {
+ rc = VINF_SUCCESS;
+ }
+
+ break;
+ }
+
+ cbTransferred += cbIO;
+
+ if (cbToTransfer < cbIO)
+ {
+ /* Transferred less than requested, do not continue with the possibly remaining data. */
+ break;
+ }
+
+ cbToTransfer = pCtx->cbData - cbTransferred;
+ if (cbToTransfer > VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE)
+ {
+ cbToTransfer = VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE;
+ }
+ }
+ }
+
+ pCtx->cbData = cbTransferred;
+
+ return rc;
+}
static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
{
NTSTATUS Status = STATUS_SUCCESS;
+ VBSFTRANSFERCTX ctx;
RxCaptureFcb;
RxCaptureFobx;
@@ -80,9 +289,20 @@ static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
return STATUS_INVALID_PARAMETER;
}
- /* @todo Split large reads. */
- vboxRC = vboxCallRead(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
- ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
+ 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);
@@ -136,6 +356,7 @@ NTSTATUS VBoxMRxRead(IN PRX_CONTEXT RxContext)
static NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
{
NTSTATUS Status = STATUS_SUCCESS;
+ VBSFTRANSFERCTX ctx;
RxCaptureFcb;
RxCaptureFobx;
@@ -174,9 +395,20 @@ static NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
return STATUS_INVALID_PARAMETER;
}
- /* @todo Split large writes. */
- vboxRC = vboxCallWrite(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
- ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
+ 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);
@@ -318,7 +550,7 @@ NTSTATUS VBoxMRxFlush (IN PRX_CONTEXT RxContext)
Status = VBoxErrorToNTStatus(vboxRC);
- Log(("VBOXSF: MRxFlush: Returned 0x%08X\n",
+ Log(("VBOXSF: MRxFlush: Returned 0x%08X\n",
Status));
return Status;
}
diff --git a/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c b/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c
index 6381dfe2..35f441e7 100644
--- a/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c
+++ b/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c
@@ -1049,6 +1049,62 @@ NTSTATUS VBoxMRxDevFcbXXXControlFile(IN OUT PRX_CONTEXT RxContext)
return Status;
}
+static NTSTATUS vbsfVerifyConnectionName(PUNICODE_STRING ConnectionName)
+{
+ /* Check that the connection name is valid:
+ * "\Device\VBoxMiniRdr\;X:\vboxsvr\sf"
+ */
+ NTSTATUS Status = STATUS_BAD_NETWORK_NAME;
+
+ ULONG i;
+ PWCHAR pwc;
+ PWCHAR pwc1;
+
+ static PWCHAR spwszPrefix = L"\\Device\\VBoxMiniRdr\\;";
+
+ /* Unicode chars in the string. */
+ ULONG cConnectionName = ConnectionName->Length / sizeof(WCHAR);
+ ULONG cRemainingName;
+
+ /* Check that the name starts with correct prefix. */
+ pwc1 = &spwszPrefix[0];
+ pwc = ConnectionName->Buffer;
+ for (i = 0; i < cConnectionName; i++, pwc1++, pwc++)
+ {
+ if (*pwc1 == 0 || *pwc == 0 || *pwc1 != *pwc)
+ {
+ break;
+ }
+ }
+
+ cRemainingName = cConnectionName - i;
+
+ Log(("VBOXSF: vbsfVerifyConnectionName: prefix %d remaining %d [%.*ls]\n",
+ *pwc1 == 0, cRemainingName, cRemainingName, &ConnectionName->Buffer[i]));
+
+ if (*pwc1 == 0)
+ {
+ /* pwc should point to a drive letter followed by ':\' that is at least 3 chars more. */
+ if (cRemainingName >= 3)
+ {
+ if ( pwc[0] >= L'A' && pwc[0] <= L'Z'
+ && pwc[1] == L':')
+ {
+ pwc += 2;
+ cRemainingName -= 2;
+
+ /* @todo should also check that the drive letter corresponds to the name. */
+ if (vboxIsPrefixOK(pwc, cRemainingName * sizeof (WCHAR)))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
static HANDLE vbsfOpenConnectionHandle(PUNICODE_STRING ConnectionName)
{
NTSTATUS Status;
@@ -1060,24 +1116,29 @@ static HANDLE vbsfOpenConnectionHandle(PUNICODE_STRING ConnectionName)
Log(("VBOXSF: vbsfOpenConnectionHandle: ConnectionName = %.*ls\n",
ConnectionName->Length / sizeof(WCHAR), ConnectionName->Buffer));
- /* Have to create a OBJ_KERNEL_HANDLE. Otherwise the driver verifier on Windows 7 bugchecks. */
- InitializeObjectAttributes(&ObjectAttributes,
- ConnectionName,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
-
- Status = ZwCreateFile(&Handle,
- SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_OPEN_IF,
- FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0);
+ Status = vbsfVerifyConnectionName(ConnectionName);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Have to create a OBJ_KERNEL_HANDLE. Otherwise the driver verifier on Windows 7 bugchecks. */
+ InitializeObjectAttributes(&ObjectAttributes,
+ ConnectionName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ Status = ZwCreateFile(&Handle,
+ SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_OPEN_IF,
+ FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+ }
if ( Status != STATUS_SUCCESS
|| Handle == INVALID_HANDLE_VALUE)
@@ -1184,7 +1245,7 @@ NTSTATUS vbsfCreateConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
if (pDeviceExtension->wszLocalConnectionName[idx] == NULL)
{
- Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d NOT allocated!\n",
+ Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d NOT allocated!\n",
idx));
Status = STATUS_INSUFFICIENT_RESOURCES;
}
@@ -1265,8 +1326,9 @@ NTSTATUS vbsfDeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
if (NT_SUCCESS(Status))
{
PFOBX Fobx = (PFOBX)pFileObject->FsContext2;
+ Log(("VBOXSF: vbsfDeleteConnection: Fobx %p\n", Fobx));
- if (NodeType(Fobx) == RDBSS_NTC_V_NETROOT)
+ if (Fobx && NodeType(Fobx) == RDBSS_NTC_V_NETROOT)
{
PV_NET_ROOT VNetRoot = (PV_NET_ROOT)Fobx;
@@ -1328,6 +1390,9 @@ NTSTATUS vbsfDeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
}
ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
+
+ Log(("VBOXSF: vbsfDeleteConnection: deleted index 0x%x\n",
+ idx));
}
}
}
@@ -1338,6 +1403,7 @@ NTSTATUS vbsfDeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
}
}
+ Log(("VBOXSF: vbsfDeleteConnection: Status 0x%08X\n", Status));
return Status;
}
diff --git a/src/VBox/Additions/WINNT/SharedFolders/np/vboxmrxnp.cpp b/src/VBox/Additions/WINNT/SharedFolders/np/vboxmrxnp.cpp
index 453c4402..d0500a8d 100644
--- a/src/VBox/Additions/WINNT/SharedFolders/np/vboxmrxnp.cpp
+++ b/src/VBox/Additions/WINNT/SharedFolders/np/vboxmrxnp.cpp
@@ -258,7 +258,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
}
}
-
+
if (dwStatus == WN_SUCCESS)
{
/* Append the remote name. */
@@ -732,7 +732,7 @@ DWORD APIENTRY NPOpenEnum(DWORD dwScope,
if (dwStatus != WN_SUCCESS)
{
- Log(("VBOXNP: NPOpenEnum: Returned error 0x%08X\n",
+ Log(("VBOXNP: NPOpenEnum: Returned error 0x%08X\n",
dwStatus));
if (pCtx)
{
@@ -859,7 +859,7 @@ DWORD APIENTRY NPEnumResource(HANDLE hEnum,
*pDst++ = L'\\';
CopyMemory(pDst, RemoteName, cbRemoteName);
pDst += cbRemoteName / sizeof(WCHAR);
-
+
pNetResource->lpComment = NULL;
pNetResource->lpProvider = pDst;
@@ -1597,7 +1597,7 @@ BOOL WINAPI DllMain(HINSTANCE hDLLInst,
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
- RTR3InitDll(0);
+ RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
VbglR3Init();
LogRel(("VBOXNP: DLL loaded.\n"));
break;