|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
netroot.c
Abstract:
This module implements the routines for creating the PROXY net root.
Author:
Balan Sethu Raman [SethuR] 7-March-1995
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// The Bug check file id for this module
//
#define BugCheckFileId (RDBSS_BUG_CHECK_PROXY_NETROOT)
//
// The local debug trace level
//
#define Dbg (DEBUG_TRACE_DISPATCH)
//
// Forward declarations ...
//
NTSTATUS MRxProxyUpdateNetRootState( IN OUT PMRX_NET_ROOT pNetRoot) /*++
Routine Description:
This routine update the mini redirector state associated with a net root.
Arguments:
pNetRoot - the net root instance.
Return Value:
RXSTATUS - The return status for the operation
Notes:
--*/ { if (pNetRoot->Context == NULL) { pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_ERROR; } else { pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD; }
return STATUS_SUCCESS; }
NTSTATUS MRxProxyCreateVNetRoot( IN OUT PMRX_V_NET_ROOT pVNetRoot, IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext ) /*++
Routine Description:
This routine patches the RDBSS created net root instance with the information required by the mini redirector.
Arguments:
pVNetRoot - the virtual net root instance.
pCreateNetRootContext - the net root context for calling back
Return Value:
RXSTATUS - The return status for the operation
Notes:
--*/ { //NTSTATUS Status;
PRX_CONTEXT pRxContext = pCreateNetRootContext->RxContext; PMRXPROXY_DEVICE_OBJECT MRxProxyDeviceObject = (PMRXPROXY_DEVICE_OBJECT)(pRxContext->RxDeviceObject);
PMRX_SRV_CALL pSrvCall; PMRX_NET_ROOT pNetRoot;
RxDbgTrace( 0, Dbg, ("MRxProxyCreateVNetRoot %lx\n",pVNetRoot)); pNetRoot = pVNetRoot->pNetRoot; pSrvCall = pNetRoot->pSrvCall;
ASSERT((NodeType(pNetRoot) == RDBSS_NTC_NETROOT) && (NodeType(pSrvCall) == RDBSS_NTC_SRVCALL));
pNetRoot->InnerNamePrefix = MRxProxyDeviceObject->InnerPrefixForOpens; pNetRoot->DiskParameters.RenameInfoOverallocationSize = MRxProxyDeviceObject->PrefixForRename.Length; pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS; pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS;
// Callback the RDBSS for resumption.
pCreateNetRootContext->Callback(pCreateNetRootContext);
// Map the error code to STATUS_PENDING since this triggers the synchronization
// mechanism in the RDBSS.
return STATUS_PENDING;
}
NTSTATUS MRxProxyFinalizeVNetRoot( IN PMRX_V_NET_ROOT pVNetRoot, IN PBOOLEAN ForceDisconnect) /*++
Routine Description:
Arguments:
pVNetRoot - the virtual net root
ForceDisconnect - disconnect is forced
Return Value:
RXSTATUS - The return status for the operation
--*/ {
RxDbgTrace( 0, Dbg, ("MRxProxyFinalizeVNetRoot %lx\n",pVNetRoot));
//return STATUS_SUCCESS;
return STATUS_NOT_IMPLEMENTED; }
NTSTATUS MRxProxyFinalizeNetRoot( IN PMRX_NET_ROOT pNetRoot, IN PBOOLEAN ForceDisconnect) /*++
Routine Description:
Arguments:
pVirtualNetRoot - the virtual net root
ForceDisconnect - disconnect is forced
Return Value:
RXSTATUS - The return status for the operation
--*/ { RxDbgTrace( 0, Dbg, ("MRxProxyFinalizeNetRoot %lx\n",pNetRoot));
//return STATUS_SUCCESS;
return STATUS_NOT_IMPLEMENTED; }
VOID ProxyCeReconnectCallback( PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext) /*++
Routine Description:
This routine signals the completion of a reconnect attempt
Arguments:
pCreateNetRootContext - the net root context
Return Value:
RXSTATUS - The return status for the operation
--*/ { KeSetEvent(&pCreateNetRootContext->FinishEvent, IO_NETWORK_INCREMENT, FALSE ); }
NTSTATUS ProxyCeReconnect( IN PMRX_V_NET_ROOT pVNetRoot) /*++
Routine Description:
This routine reconnects, i.e, establishes a new session and tree connect to a previously connected serverb share
Arguments:
pVNetRoot - the virtual net root instance.
Return Value:
RXSTATUS - The return status for the operation
--*/ { NTSTATUS Status;
PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext;
pCreateNetRootContext = (PMRX_CREATENETROOT_CONTEXT) RxAllocatePoolWithTag( NonPagedPool, sizeof(MRX_CREATENETROOT_CONTEXT), MRXPROXY_NETROOT_POOLTAG);
if (pCreateNetRootContext != NULL) { pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS; pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS; pCreateNetRootContext->Callback = ProxyCeReconnectCallback; pCreateNetRootContext->RxContext = NULL; KeInitializeEvent( &pCreateNetRootContext->FinishEvent, SynchronizationEvent, FALSE );
// Since this is a reconnect instance the net root initialization is not required
#if 0
Status = ProxyCeEstablishConnection( pVNetRoot, pCreateNetRootContext, FALSE); #endif
Status = STATUS_SUCCESS;
if (Status == STATUS_PENDING) { // Wait for the construction to be completed.
KeWaitForSingleObject(&pCreateNetRootContext->FinishEvent, Executive, KernelMode, FALSE, NULL); Status = pCreateNetRootContext->VirtualNetRootStatus; }
RxFreePool(pCreateNetRootContext); } else { Status = STATUS_INSUFFICIENT_RESOURCES; }
return Status; }
NTSTATUS ProxyCeEstablishConnection( IN OUT PMRX_V_NET_ROOT pVNetRoot, IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext, IN BOOLEAN fInitializeNetRoot ) /*++
Routine Description:
This routine triggers off the connection attempt for initial establishment of a connection as well as subsequent reconnect attempts.
Arguments:
pVNetRoot - the virtual net root instance.
pCreateNetRootContext - the net root context for calling back
Return Value:
RXSTATUS - The return status for the operation
Notes: CODE.IMPROVEMENT -- The net root create context must supply the open mode in order to enable the mini redirector to implement a wide variety of reconnect strategies.
--*/ { NTSTATUS Status; #if 0
PPROXYCEDB_SERVER_ENTRY pServerEntry; PPROXYCEDB_SESSION_ENTRY pSessionEntry; PPROXYCEDB_NET_ROOT_ENTRY pNetRootEntry; PPROXYCE_V_NET_ROOT_CONTEXT pVNetRootContext;
pVNetRootContext = ProxyCeGetAssociatedVNetRootContext(pVNetRoot); if (pVNetRootContext == NULL) { Status = STATUS_BAD_NETWORK_PATH; } else { pServerEntry = pVNetRootContext->pServerEntry; pSessionEntry = pVNetRootContext->pSessionEntry; pNetRootEntry = pVNetRootContext->pNetRootEntry; Status = STATUS_SUCCESS; }
if (Status != STATUS_SUCCESS) { return Status; }
if ((pServerEntry->Server.DialectFlags & DF_EXTENDED_SECURITY) && (pSessionEntry->Header.State != PROXYCEDB_ACTIVE)) { PPROXY_EXCHANGE pSessionSetupExchange;
pSessionSetupExchange = ProxyMmAllocateExchange(EXTENDED_SESSION_SETUP_EXCHANGE,NULL); if (pSessionSetupExchange != NULL) { Status = ProxyCeInitializeExtendedSessionSetupExchange( &pSessionSetupExchange, pVNetRoot);
if (Status == STATUS_SUCCESS) { PROXYCE_RESUMPTION_CONTEXT ExchangeResumptionContext; // Attempt to reconnect( In this case it amounts to establishing the
// connection/session)
pSessionSetupExchange->ProxyCeFlags |= PROXYCE_EXCHANGE_ATTEMPT_RECONNECTS;
ProxyCeInitializeResumptionContext(&ExchangeResumptionContext);
((PPROXY_EXTENDED_SESSION_SETUP_EXCHANGE)pSessionSetupExchange)->pResumptionContext = &ExchangeResumptionContext;
Status = ProxyCeInitiateExchange(pSessionSetupExchange);
if (Status == STATUS_PENDING) { ProxyCeSuspend( &ExchangeResumptionContext);
Status = ExchangeResumptionContext.Status; } else { ProxyCeDiscardExtendedSessionSetupExchange( (PPROXY_EXTENDED_SESSION_SETUP_EXCHANGE)pSessionSetupExchange); } } else { ProxyMmFreeExchange(pSessionSetupExchange); } } else { Status = STATUS_INSUFFICIENT_RESOURCES; } }
if (Status == STATUS_SUCCESS) { //
// The following code initializes the NetRootEntry, VNetRootContext and
// the session entry under certain cases.
//
// The session entry to a doenlevel server needs to be initialized. This
// is not handled by the previous code since the session entry and the
// net root entry initialization can be combined into one exchange.
//
// The net root entry has not been initialized, i.e., this corresponds to
// the construction of the first PROXYCE_V_NET_ROOT_CONTEXT instance for a
// given NetRootEntry.
//
// Subsequent PROXYCE_V_NET_ROOT context constructions. In these cases the
// construction of each context must obtain a new TID
//
BOOLEAN fNetRootExchangeRequired;
fNetRootExchangeRequired = ( ((pSessionEntry->Header.State != PROXYCEDB_ACTIVE) && !(pServerEntry->Server.DialectFlags & DF_EXTENDED_SECURITY)) || !BooleanFlagOn( pVNetRootContext->Flags, PROXYCE_V_NET_ROOT_CONTEXT_FLAG_VALID_TID) );
if (fNetRootExchangeRequired) { // This is a tree connect open which needs to be triggered immediately.
PPROXY_EXCHANGE pProxyExchange; PPROXY_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
pProxyExchange = ProxyMmAllocateExchange(CONSTRUCT_NETROOT_EXCHANGE,NULL); if (pProxyExchange != NULL) { Status = ProxyCeInitializeExchange( &pProxyExchange, pVNetRoot, CONSTRUCT_NETROOT_EXCHANGE, &ConstructNetRootExchangeDispatch);
if (Status == RX_MAP_STATUS(SUCCESS)) { pNetRootExchange = (PPROXY_CONSTRUCT_NETROOT_EXCHANGE)pProxyExchange;
// Attempt to reconnect( In this case it amounts to establishing the
// connection/session)
pNetRootExchange->ProxyCeFlags |= PROXYCE_EXCHANGE_ATTEMPT_RECONNECTS; // Initialize the continuation for resumption upon completion of the
// tree connetcion.
pNetRootExchange->NetRootCallback = pCreateNetRootContext->Callback; pNetRootExchange->pCreateNetRootContext = pCreateNetRootContext;
pNetRootExchange->fInitializeNetRoot = fInitializeNetRoot;
// Initiate the exchange.
Status = ProxyCeInitiateExchange(pProxyExchange);
if (Status != STATUS_PENDING) { ProxyCeDiscardExchange(pProxyExchange); } } } else { Status = STATUS_INSUFFICIENT_RESOURCES; } } } #endif
Status = STATUS_SUCCESS; return Status; }
VOID MRxProxyExtractNetRootName( IN PUNICODE_STRING FilePathName, IN PMRX_SRV_CALL SrvCall, OUT PUNICODE_STRING NetRootName, OUT PUNICODE_STRING RestOfName OPTIONAL ) /*++
Routine Description:
This routine parses the input name into srv, netroot, and the rest.
Arguments:
--*/ { UNICODE_STRING xRestOfName;
ULONG length = FilePathName->Length; PWCH w = FilePathName->Buffer; PWCH wlimit = (PWCH)(((PCHAR)w)+length); PWCH wlow;
w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR)); NetRootName->Buffer = wlow = w; for (;;) { if (w>=wlimit) break; if ( (*w == OBJ_NAME_PATH_SEPARATOR) && (w!=wlow) ){ #if ZZZ_MODE
if (*(w-1) == L'z') { w++; continue; } #endif //if ZZZ_MODE
break; } w++; } NetRootName->Length = NetRootName->MaximumLength = (PCHAR)w - (PCHAR)wlow;
if (!RestOfName) RestOfName = &xRestOfName; RestOfName->Buffer = w; RestOfName->Length = RestOfName->MaximumLength = (PCHAR)wlimit - (PCHAR)w;
RxDbgTrace( 0,Dbg,(" MRxProxyExtractNetRootName FilePath=%wZ\n",FilePathName)); RxDbgTrace(0,Dbg,(" Srv=%wZ,Root=%wZ,Rest=%wZ\n", SrvCall->pSrvCallName,NetRootName,RestOfName));
return; }
|