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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|