353 lines
8.4 KiB
C
353 lines
8.4 KiB
C
/*++
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
|