|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
devfcb.c
Abstract:
This module implements all the passthru stuff from the wrapper. currently there is only one such functions: statistics
Revision History:
Balan Sethu Raman [SethuR] 16-July-1995
Notes:
--*/
#include "precomp.h"
#pragma hdrstop
#include "fsctlbuf.h"
//
// The local trace mask for this part of the module
//
#define Dbg (DEBUG_TRACE_DEVFCB)
typedef enum _MRXPROXY_STATE_ { MRXPROXY_STARTABLE, MRXPROXY_START_IN_PROGRESS, MRXPROXY_STARTED } MRXPROXY_STATE,*PMRXPROXY_STATE;
MRXPROXY_STATE MRxProxyState = MRXPROXY_STARTABLE;
NTSTATUS MRxProxyTestDevIoctl( IN PRX_CONTEXT RxContext );
NTSTATUS MRxProxyExternalStart ( IN PRX_CONTEXT RxContext );
NTSTATUS MRxProxySetupClaimedServerList( IN PRX_CONTEXT RxContext );
VOID MRxProxyDereferenceClaimedServers(void);
NTSTATUS MRxProxyDevFcbXXXControlFile ( IN OUT PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine handles all the device FCB related FSCTL's in the mini rdr
Arguments:
RxContext - Describes the Fsctl and Context.
Return Value:
RxStatus(SUCCESS) -- the Startup sequence was successfully completed.
any other value indicates the appropriate error in the startup sequence.
Notes:
--*/ { NTSTATUS Status; RxCaptureFobx; UCHAR MajorFunctionCode = RxContext->MajorFunction; PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext; ULONG ControlCode = LowIoContext->ParamsFor.FsCtl.FsControlCode;
RxDbgTrace(+1, Dbg, ("MRxProxyDevFcb\n")); switch (MajorFunctionCode) { case IRP_MJ_FILE_SYSTEM_CONTROL: {
switch (LowIoContext->ParamsFor.FsCtl.MinorFunction) { case IRP_MN_USER_FS_REQUEST: switch (ControlCode) {
case FSCTL_PROXY_START: ASSERT (!capFobx); Status = MRxProxyExternalStart( RxContext ); break;
case FSCTL_PROXY_STOP: ASSERT (!capFobx); MRxProxyDereferenceClaimedServers(); Status = RxStopMinirdr( RxContext, &RxContext->PostRequest ); break;
default: Status = STATUS_INVALID_DEVICE_REQUEST; } break; default : //minor function != IRP_MN_USER_FS_REQUEST
Status = STATUS_INVALID_DEVICE_REQUEST; } // end of switch
} // end of FSCTL case
break; case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_INTERNAL_DEVICE_CONTROL: { switch (ControlCode) { #if DBG
case IOCTL_LMMR_TEST: Status = MRxProxyTestDevIoctl(RxContext); break; #endif //if DBG
default : Status = STATUS_INVALID_DEVICE_REQUEST; } // end of switch
} //end of IOCTL cases
break; default: ASSERT(!"unimplemented major function"); Status = STATUS_INVALID_DEVICE_REQUEST;
}
RxDbgTrace(-1, Dbg, ("MRxProxyDevFcb st,info=%08lx,%08lx\n", Status,RxContext->InformationToReturn)); return(Status);
}
#if DBG
NTSTATUS MRxProxyTestDevIoctl( IN PRX_CONTEXT RxContext ) { NTSTATUS Status = STATUS_SUCCESS; PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
PSZ InputString = LowIoContext->ParamsFor.FsCtl.pInputBuffer; PSZ OutputString = LowIoContext->ParamsFor.FsCtl.pOutputBuffer; ULONG OutputBufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength; ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
ULONG i;
//BUGBUG because this is a method neither, the buffers have not been probed. since this is debug
//only i am foregoing that currently. when we do more here...we'll have to probe.
RxDbgTrace(0, Dbg,("MRxProxyTestDevIoctl %s, obl = %08lx\n",InputString, OutputBufferLength)); RxContext->InformationToReturn = (InputBufferLength-1)*(InputBufferLength-1);
for (i=0;i<InputBufferLength;i++) { UCHAR c = InputString[i]; if (c==0) { break; } OutputString[i] = c; if ((i&3)==2) { OutputString[i] = '@'; } } OutputString[i] = 0;
return(Status); } #endif //if DBG
NTSTATUS MRxProxyExternalStart ( IN PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine starts up the proxy minirdr if it hasn't been started already.
Arguments:
RxContext - Describes the Fsctl and Context.
Return Value:
STATUS_SUCCESS -- the Startup sequence was successfully completed.
any other value indicates the appropriate error in the startup sequence.
--*/ { NTSTATUS Status; BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
PAGED_CODE();
//DbgBreakPoint();
RxDbgTrace(0, Dbg, ("MRxProxyExternalStart [Start] -> %08lx\n", 0));
Status = RxStartMinirdr( RxContext, &RxContext->PostRequest ); if (Status == STATUS_SUCCESS) { MRXPROXY_STATE State;
MRxProxySetupClaimedServerList(RxContext);
State = (MRXPROXY_STATE)InterlockedCompareExchange( (PVOID *)&MRxProxyState, (PVOID)MRXPROXY_STARTED, (PVOID)MRXPROXY_START_IN_PROGRESS);
if (State != MRXPROXY_START_IN_PROGRESS) { Status = STATUS_REDIRECTOR_STARTED; } }
return Status; }
//CODE.IMPROVEMENT we should get this from the registry........
struct { PWCHAR ServerName; PSRV_CALL SrvCall; ULONG Flags; } MRxProxyClaimedServerList[] = { {MRXPROXY_CLAIMED_SERVERNAME_U,NULL,0}, NULL };
NTSTATUS MRxProxySetupClaimedServerList( IN PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine claims servers for this module. Arguments:
none
Return Value:
RXSTATUS - could return an error if an allocation fails or something
--*/ { ULONG i;
PAGED_CODE();
RxAcquirePrefixTableLockExclusive( &RxNetNameTable, TRUE);
try { for (i=0;MRxProxyClaimedServerList[i].ServerName!=NULL;i++) { PWCHAR ServerNameText = MRxProxyClaimedServerList[i].ServerName; ULONG Flags = MRxProxyClaimedServerList[i].Flags; UNICODE_STRING SrvCallName,UnmatchedName; PVOID Container = NULL; PSRV_CALL SrvCall;
RtlInitUnicodeString(&SrvCallName,ServerNameText); DbgPrint("CLAIMEDSERVER %wZ %08lx\n",&SrvCallName,Flags); Container = RxPrefixTableLookupName( &RxNetNameTable, &SrvCallName, &UnmatchedName ); if (Container!=NULL) { ASSERT ( NodeType(Container) == RDBSS_NTC_SRVCALL); SrvCall = (PSRV_CALL)Container; //this leaves a reference!
} else { //here we have to create the srvcall
SrvCall = RxCreateSrvCall(RxContext,&SrvCallName,NULL); if (SrvCall == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } RxReferenceSrvCall(SrvCall); //leave this reference
}
SrvCall->Flags |= Flags; SrvCall->RxDeviceObject = &MRxProxyDeviceObject->RxDeviceObject; if (FlagOn(SrvCall->Flags,SRVCALL_FLAG_NO_CONNECTION_ALLOWED)) { SrvCall->Condition = Condition_Bad; } else { SrvCall->Condition = Condition_Good; } MRxProxyClaimedServerList[i].SrvCall = SrvCall; //remember this for later
} } finally {
RxReleasePrefixTableLock( &RxNetNameTable );
}
return(STATUS_SUCCESS); }
VOID MRxProxyDereferenceClaimedServers( void ) /*++
Routine Description:
This routine tears down the list of claimed servers. it does this by just removing a reference; this will make the servers eligible for finalization in finalizenettable.
Arguments:
none
Return Value:
none
--*/ { ULONG i; LOCK_HOLDING_STATE LockHoldingState = LHS_LockNotHeld;
PAGED_CODE();
for (i=0;MRxProxyClaimedServerList[i].ServerName!=NULL;i++) { PSRV_CALL SrvCall = MRxProxyClaimedServerList[i].SrvCall;
if (SrvCall != NULL) { DbgPrint("Claimed Srvcall deref %wZ\n",&SrvCall->PrefixEntry.Prefix); MRxProxyClaimedServerList[i].SrvCall = NULL; RxDereferenceSrvCall(SrvCall,LockHoldingState); } } }
|