/** @file
*
* VirtualBox Windows Guest Shared Folders
*
* File System Driver network redirector subsystem routines
*/
/*
* Copyright (C) 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;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "vbsf.h"
{
Log(("VBOXSF: MRxUpdateNetRootState\n"));
return STATUS_NOT_IMPLEMENTED;
}
{
Log(("VBOXSF: vbsfUpdateNetRoot: NetRoot = 0x%x Type = 0x%x\n",
{
case NET_ROOT_DISK:
break;
case NET_ROOT_PIPE:
break;
case NET_ROOT_COMM:
break;
case NET_ROOT_PRINT:
break;
case NET_ROOT_MAILSLOT:
break;
case NET_ROOT_WILD:
/* We get this type when for example Windows Media player opens an MP3 file.
* This NetRoot has the same remote path (\\vboxsrv\dir) as other NetRoots,
* which were created earlier and which were NET_ROOT_DISK.
*
* In the beginning of the function (UpdateNetRoot) the DDK sample sets
* pNetRoot->Type of newly created NetRoots using a value previously
* pstored in a NetRootExtension. One NetRootExtensions is used for a single
* remote path and reused by a few NetRoots, if they point to the same path.
*
* To simplify things we just set the type to DISK here (we do not support
* anything else anyway), and update the DeviceType correspondingly.
*/
break;
default:
AssertMsgFailed(("VBOXSF: vbsfUpdateNetRoot: Invalid net root type! Type = 0x%x\n",
break;
}
Log(("VBOXSF: vbsfUpdateNetRoot: leaving pNetRoot->DeviceType = 0x%x\n",
pNetRoot->DeviceType));
}
{
PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(pCreateNetRootContext->RxContext);
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.
*/
{
/* 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.
*/
if (pNetRoot->pNetRootName->Length >= 13 * sizeof (WCHAR)) /* Number of bytes in '\vboxsrv\ipc$' unicode string. */
{
if ( Suffix[0] == L'\\'
)
{
)
{
/* It is '\vboxsrv\IPC$[\*]'. */
Log(("VBOXSF: MRxCreateVNetRoot: IPC$\n"));
goto l_Exit;
}
}
}
/* Fail all other pipe open requests. */
Log(("VBOXSF: MRxCreateVNetRoot: Pipe open not supported!\n"));
goto l_Exit;
}
{
Log(("VBOXSF: MRxCreateVNetRoot: Mailslot open not supported!\n"));
goto l_Exit;
}
{
/* 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"));
goto l_Exit;
}
/* Detect an already initialized NetRoot.
* pNetRootExtension is actually the pNetRoot->Context and it is not NULL.
*/
if (fInitializeNetRoot)
{
int vboxRC;
Log(("VBOXSF: MRxCreateVNetRoot: initialize NET_ROOT\n"));
if (RootNameLength < sizeof(WCHAR))
{
/* Refuse a netroot path with an empty shared folder name */
Log(("VBOXSF: MRxCreateVNetRoot: Empty shared folder name!\n"));
goto l_Exit;
}
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)
RootNameLength -= sizeof(WCHAR);
if (!pNetRootExtension->phgcmClient)
{
Log(("VBOXSF: MRxCreateVNetRoot: Initialize netroot length = %d, name = %.*ls\n",
if (Status != STATUS_SUCCESS)
{
goto l_Exit;
}
if (vboxRC != VINF_SUCCESS)
{
}
else
{
}
}
}
else
Log(("VBOXSF: MRxCreateVNetRoot: Creating V_NET_ROOT on existing NET_ROOT!\n"));
if (Status != STATUS_PENDING)
{
if (fInitializeNetRoot)
else
/* Inform RDBSS. */
/* RDBSS expects this. */
}
Log(("VBOXSF: MRxCreateVNetRoot: Returned STATUS_PENDING\n"));
return Status;
}
{
Log(("VBOXSF: MRxFinalizeVNetRoot: V_NET_ROOT %p, NET_ROOT %p\n",
return STATUS_SUCCESS;
}
{
if (pNetRootExtension->phgcmClient)
{
if (vboxRC != VINF_SUCCESS)
Log(("VBOXSF: MRxFinalizeVNetRoot: vboxCallUnmapFolder failed with %d\n",
vboxRC));
}
return STATUS_SUCCESS;
}
{
int iNetRoot;
int i;
/* Split "\vboxsvr\share\path" to
* NetRootName = "\share"
* RestOfName = "\path"
*
* Note that SrvCall->pSrvCallName contains "\vboxsrv".
*/
Log(("VBOXSF: MRxExtractNetRootName: [%.*ls], RestOfName %p\n",
/* Assume that the server prefix is OK.
* iNetRoot points to the first char after server name, the delimiter.
*/
/* Find the NetRoot length: end of FilePathName or the next delimiter. */
i = iNetRoot;
while (i < cChars)
{
&& i > iNetRoot)
{
break;
}
i++;
}
Log(("VBOXSF: MRxExtractNetRootName: cChars %d, iNetRoot %d, iRest %d\n",
Log(("VBOXSF: MRxExtractNetRootName: Srv = %.*ls, Root = %.*ls\n",
if (RestOfName)
{
Log(("VBOXSF: MRxExtractNetRootName: Rest = %.*ls\n",
}
}
{
PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure = (PMRX_SRVCALLDOWN_STRUCTURE)(SCCBC->SrvCalldownStructure);
/* Validate the server name with the test name of 'vboxsvr'. */
Log(("VBOXSF: vbsfExecuteCreateSrvCall: Connection Name %.*ls Length: %d, pSrvCall = %p\n",
pSrvCall->pSrvCallName->Length / sizeof(WCHAR), pSrvCall->pSrvCallName->Buffer, pSrvCall->pSrvCallName->Length, pSrvCall));
{
Log(("VBOXSF: vbsfExecuteCreateSrvCall: Principal name = %.*ls\n",
}
{
Log(("VBOXSF: vbsfExecuteCreateSrvCall: Domain name = %.*ls\n",
}
{
/* Both vboxsvr & vboxsrv are now accepted */
{
}
else
{
}
}
else
if (Verifier)
{
Log(("VBOXSF: vbsfExecuteCreateSrvCall: Verifier succeeded!\n"));
}
else
{
Log(("VBOXSF: vbsfExecuteCreateSrvCall: Verifier failed!\n"));
}
}
{
PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure = (PMRX_SRVCALLDOWN_STRUCTURE)(pCallbackContext->SrvCalldownStructure);
if (IoGetCurrentProcess() == RxGetRDBSSProcess())
{
Log(("VBOXSF: MRxCreateSrvCall: Called in context of RDBSS process\n"));
}
else
{
Log(("VBOXSF: MRxCreateSrvCall: Dispatching to worker thread\n"));
if (Status == STATUS_SUCCESS)
Log(("VBOXSF: MRxCreateSrvCall: queued\n"));
else
{
}
}
/* RDBSS expect this. */
return STATUS_PENDING;
}
{
return STATUS_SUCCESS;
}
{
Log(("VBOXSF: MRxSrvCallWinnerNotify: pSrvCall %p, pSrvCall->Ctx %p, winner %d, context %p\n",
/* Set it to not NULL. */
return STATUS_SUCCESS;
}