594 lines
18 KiB
C
594 lines
18 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
read.c
|
||
|
||
Abstract:
|
||
|
||
This module implements the mini redirector call down routines pertaining to
|
||
file system control(FSCTL) and Io Device Control (IOCTL) operations on file system objects.
|
||
|
||
Author:
|
||
|
||
Balan Sethu Raman [SethuR] 7-March-1995
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
#include <dfsfsctl.h>
|
||
|
||
//
|
||
// The local debug trace level
|
||
//
|
||
|
||
|
||
RXDT_DefineCategory(FSCTRL);
|
||
#define Dbg (DEBUG_TRACE_FSCTRL)
|
||
|
||
NTSTATUS
|
||
MRxProxyFsCtl(
|
||
IN OUT PRX_CONTEXT RxContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine performs an FSCTL operation (remote) on a file across the network
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
Notes:
|
||
|
||
The FSCTL's handled by a mini rdr can be classified into one of two categories. In the
|
||
first category are those FSCTL's whose implementation are shared between RDBSS and the
|
||
mini rdr's and in the second category are those FSCTL's which are totally implemented
|
||
by the mini rdr's. To this a third category can be added, i.e., those FSCTL's which
|
||
should never be seen by the mini rdr's. The third category is solely intended as a
|
||
debugging aid.
|
||
|
||
The FSCTL's handled by a mini rdr can be classified based on functionality
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
|
||
|
||
PLOWIO_CONTEXT pLowIoContext = &RxContext->LowIoContext;
|
||
ULONG FsControlCode = pLowIoContext->ParamsFor.FsCtl.FsControlCode;
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxProxyFsCtl...\n", 0));
|
||
RxDbgTrace( 0, Dbg, ("MRxProxyFsCtl = %08lx\n", FsControlCode));
|
||
|
||
switch (pLowIoContext->ParamsFor.FsCtl.MinorFunction) {
|
||
case IRP_MN_USER_FS_REQUEST:
|
||
switch (FsControlCode) {
|
||
case FSCTL_PIPE_ASSIGN_EVENT :
|
||
case FSCTL_PIPE_DISCONNECT :
|
||
case FSCTL_PIPE_LISTEN :
|
||
case FSCTL_PIPE_PEEK :
|
||
case FSCTL_PIPE_QUERY_EVENT :
|
||
case FSCTL_PIPE_TRANSCEIVE :
|
||
case FSCTL_PIPE_WAIT :
|
||
case FSCTL_PIPE_IMPERSONATE :
|
||
case FSCTL_PIPE_SET_CLIENT_PROCESS :
|
||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS :
|
||
case FSCTL_MAILSLOT_PEEK :
|
||
case FSCTL_DFS_GET_REFERRALS:
|
||
case FSCTL_DFS_REPORT_INCONSISTENCY:
|
||
case FSCTL_LMR_TRANSACT :
|
||
default:
|
||
// Status = MRxProxyFsControl(RxContext);
|
||
// Temporarily stubbed out till the buffer passing strategy has been
|
||
// finalized.
|
||
Status = STATUS_NOT_IMPLEMENTED;
|
||
break;
|
||
}
|
||
break;
|
||
default :
|
||
break;
|
||
}
|
||
|
||
RxDbgTrace(-1, Dbg, ("MRxProxyFsCtl -> %08lx\n", Status ));
|
||
return Status;
|
||
}
|
||
|
||
typedef struct _PROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT_ {
|
||
PRX_CONTEXT pRxContext;
|
||
//REQ_NOTIFY_CHANGE NotifyRequest;
|
||
//PROXY_TRANSACTION_OPTIONS Options;
|
||
//PROXY_TRANSACTION_RESUMPTION_CONTEXT ResumptionContext;
|
||
} PROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT, *PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT;
|
||
|
||
VOID
|
||
MRxProxyNotifyChangeDirectoryCompletion(
|
||
PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT pNotificationContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is invokde when a directory change notification operation is completed
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
Notes:
|
||
|
||
This routine will always be called. This is true even if the change directory
|
||
notification is cancelled. In such cases the memory allocated is freed without
|
||
any inteaction with the wrapped. In cases os successful directory change
|
||
notification completion the appropriate completion routine is invoked and the
|
||
RxContext modified to prevent any cancellation from proceeding further.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
PRX_CONTEXT pRxContext;
|
||
PMRXPROXY_RX_CONTEXT pMRxProxyContext;
|
||
//PPROXY_EXCHANGE pExchange = NULL;
|
||
|
||
ProxyAcquireGlobalSpinLock();
|
||
|
||
pRxContext = pNotificationContext->pRxContext;
|
||
|
||
if (pRxContext != NULL) {
|
||
// This is a case of successful completion of the change directory
|
||
// notification, i.e., the request was not cancelled. In such cases
|
||
// prevent all race conditions by modifying the RxContext under lock
|
||
// to turn back cancellation request.
|
||
|
||
pMRxProxyContext = MRxProxyGetMinirdrContext(pRxContext);
|
||
//pExchange = pMRxProxyContext->pExchange;
|
||
|
||
pMRxProxyContext->pCancelContext = NULL;
|
||
pNotificationContext->pRxContext = NULL;
|
||
}
|
||
|
||
ProxyReleaseGlobalSpinLock();
|
||
|
||
// Complete the Context if it was not previously cancelled
|
||
if (pRxContext != NULL) {
|
||
//PPROXY_TRANSACTION_RESUMPTION_CONTEXT pResumptionContext;
|
||
|
||
//pResumptionContext = &(pNotificationContext->ResumptionContext);
|
||
|
||
//pRxContext->StoredStatus = pResumptionContext->FinalStatusFromServer;
|
||
|
||
Status = RxSetMinirdrCancelRoutine(pRxContext,NULL);
|
||
if (Status == STATUS_SUCCESS) {
|
||
RxLowIoCompletion(pRxContext);
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
// Free the associated exchange.
|
||
if (pExchange != NULL) {
|
||
ProxyCeDereferenceAndDiscardExchange(pExchange);
|
||
}
|
||
#endif //0
|
||
|
||
// Free the notification context.
|
||
RxFreePool(pNotificationContext);
|
||
}
|
||
|
||
NTSTATUS
|
||
MRxProxyNotifyChangeDirectoryCancellation(
|
||
PRX_CONTEXT RxContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is invokde when a directory change notification operation is cancelled.
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - The return status for the operation
|
||
|
||
--*/
|
||
{
|
||
//NTSTATUS Status;
|
||
|
||
BOOLEAN ChangeDirectoryNotificationCompleted;
|
||
|
||
PMRXPROXY_RX_CONTEXT pMRxProxyContext = MRxProxyGetMinirdrContext(RxContext);
|
||
//PPROXY_EXCHANGE pExchange;
|
||
|
||
PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT pNotificationContext;
|
||
|
||
ProxyAcquireGlobalSpinLock();
|
||
|
||
pNotificationContext = (PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT)pMRxProxyContext->pCancelContext;
|
||
ChangeDirectoryNotificationCompleted = (pNotificationContext == NULL);
|
||
|
||
if (!ChangeDirectoryNotificationCompleted) {
|
||
// This is a case of successful cancellation of the change directory
|
||
// notification. In such cases prevent all race conditions by modifying
|
||
// the RxContext under lock to prevent successful completion
|
||
|
||
pNotificationContext->pRxContext = NULL;
|
||
//pExchange = pMRxProxyContext->pExchange;
|
||
|
||
pMRxProxyContext->pCancelContext = NULL;
|
||
}
|
||
|
||
ProxyReleaseGlobalSpinLock();
|
||
|
||
if (ChangeDirectoryNotificationCompleted) {
|
||
// The cancellation is trivial since the request has already been completed
|
||
return STATUS_SUCCESS;
|
||
}
|
||
#if 0 //can't do any of this....no exchanges.........
|
||
if (pExchange != NULL) {
|
||
UCHAR LastCommandInHeader;
|
||
PUCHAR pCommand;
|
||
|
||
BYTE CancelRequestBuffer[sizeof(PROXY_HEADER) + sizeof(REQ_NT_CANCEL)];
|
||
ULONG CancelRequestBufferSize = sizeof(CancelRequestBuffer);
|
||
|
||
// Build the Cancel request and send it across to the server.
|
||
Status = ProxyCeBuildProxyHeader(
|
||
pExchange,
|
||
CancelRequestBuffer,
|
||
CancelRequestBufferSize,
|
||
&CancelRequestBufferSize,
|
||
&LastCommandInHeader,
|
||
&pCommand);
|
||
|
||
ASSERT(LastCommandInHeader == PROXY_COM_NO_ANDX_COMMAND);
|
||
|
||
*pCommand = PROXY_COM_NT_CANCEL;
|
||
|
||
if (Status == RX_MAP_STATUS(SUCCESS)) {
|
||
PREQ_NT_CANCEL pCancelRequest = (PREQ_NT_CANCEL)(&CancelRequestBuffer[sizeof(PROXY_HEADER)]);
|
||
PMDL pCancelProxyMdl;
|
||
|
||
ProxyPutUshort(&pCancelRequest->WordCount,0);
|
||
pCancelRequest->ByteCount = 0;
|
||
CancelRequestBufferSize = sizeof(CancelRequestBuffer);
|
||
|
||
pCancelProxyMdl = RxAllocateMdl(CancelRequestBuffer,CancelRequestBufferSize);
|
||
if (pCancelProxyMdl != NULL) {
|
||
RxProbeAndLockPages(pCancelProxyMdl,KernelMode,IoModifyAccess,Status);
|
||
|
||
if (Status == STATUS_SUCCESS) {
|
||
Status = ProxyCeSend(
|
||
pExchange,
|
||
RXCE_SEND_SYNCHRONOUS,
|
||
pCancelProxyMdl,
|
||
CancelRequestBufferSize);
|
||
|
||
MmUnlockPages(pCancelProxyMdl);
|
||
}
|
||
|
||
IoFreeMdl(pCancelProxyMdl);
|
||
}
|
||
}
|
||
|
||
ProxyCeDereferenceAndDiscardExchange(pExchange);
|
||
}
|
||
#endif //0
|
||
|
||
// Complete the request.
|
||
RxContext->StoredStatus = STATUS_CANCELLED;
|
||
|
||
RxLowIoCompletion(RxContext);
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
NTSTATUS
|
||
MRxProxyNotifyChangeDirectory(
|
||
IN OUT PRX_CONTEXT RxContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine performs a directory change notification operation
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
Notes:
|
||
|
||
THIS STUFF IS WRONG!!!!!
|
||
A directory change notification opertaion is an asychronous operation. It
|
||
consists of sending a PROXY requesting change notification whose response is
|
||
obtained when the desired change is affected on the server.
|
||
|
||
Some important points to remember are as follows .....
|
||
|
||
1) The PROXY response is not obtained till the desired change is affected on
|
||
the server. Therefore an additional MID needs to be reserved on those
|
||
connections which permit multiple MID's so that a cancel PROXY can be sent to
|
||
the server when a change notification is active.
|
||
|
||
2) The Change notification is typical of a long term ( response time
|
||
dictated by factors beyond the servers control). Another example is
|
||
the query FSCTL operation in CAIRO. For all these operations we initiate
|
||
an asychronous transact exchange.
|
||
|
||
3) The corresponding LowIo completion routine is invoked asynchronously.
|
||
|
||
4) This is an example of an operation for which the MINI RDR has to
|
||
register a context for handling cancellations initiated locally.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
RxCaptureFcb;
|
||
PLOWIO_CONTEXT pLowIoContext = &RxContext->LowIoContext;
|
||
|
||
//PPROXYCEDB_SERVER_ENTRY pServerEntry;
|
||
//PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT pNotificationContext;
|
||
|
||
#if 0
|
||
PBYTE pInputParamBuffer = NULL;
|
||
PBYTE pOutputParamBuffer = NULL;
|
||
PBYTE pInputDataBuffer = NULL;
|
||
PBYTE pOutputDataBuffer = NULL;
|
||
|
||
ULONG InputParamBufferLength = 0;
|
||
ULONG OutputParamBufferLength = 0;
|
||
ULONG InputDataBufferLength = 0;
|
||
ULONG OutputDataBufferLength = 0;
|
||
#endif //0
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxNotifyChangeDirectory...Entry\n", 0));
|
||
|
||
//pServerEntry = ProxyCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);
|
||
//if (!FlagOn(pServerEntry->Server.DialectFlags,DF_NT_PROXYS)) {
|
||
// return STATUS_NOT_SUPPORTED;
|
||
//}
|
||
|
||
#if 0
|
||
pNotificationContext =
|
||
(PPROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT)
|
||
RxAllocatePoolWithTag(
|
||
NonPagedPool,
|
||
sizeof(PROXY_NOTIFY_CHANGE_DIRECTORY_CONTEXT),
|
||
MRXPROXY_FSCTL_POOLTAG);
|
||
|
||
if (pNotificationContext != NULL) {
|
||
PREQ_NOTIFY_CHANGE pNotifyRequest;
|
||
PPROXY_TRANSACTION_OPTIONS pTransactionOptions;
|
||
PPROXY_TRANSACTION_RESUMPTION_CONTEXT pResumptionContext;
|
||
PMRX_PROXY_SRV_OPEN pProxySrvOpen;
|
||
|
||
RxCaptureFobx;
|
||
ASSERT (capFobx != NULL);
|
||
|
||
Status = MRxProxyDeferredCreate(RxContext);
|
||
|
||
if (Status==STATUS_SUCCESS) {
|
||
|
||
pProxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen);
|
||
|
||
ASSERT (!FlagOn(pProxySrvOpen->Flags,PROXY_SRVOPEN_FLAG_NOT_REALLY_OPEN));
|
||
pNotificationContext->pRxContext = RxContext;
|
||
|
||
pNotifyRequest = &(pNotificationContext->NotifyRequest);
|
||
pTransactionOptions = &(pNotificationContext->Options);
|
||
pResumptionContext = &(pNotificationContext->ResumptionContext);
|
||
|
||
pNotifyRequest->CompletionFilter = pLowIoContext->ParamsFor.NotifyChangeDirectory.CompletionFilter;
|
||
pNotifyRequest->Fid = pProxySrvOpen->Fid;
|
||
pNotifyRequest->WatchTree = pLowIoContext->ParamsFor.NotifyChangeDirectory.WatchTree;
|
||
pNotifyRequest->Reserved = 0;
|
||
|
||
OutputDataBufferLength = pLowIoContext->ParamsFor.NotifyChangeDirectory.NotificationBufferLength;
|
||
pOutputDataBuffer = pLowIoContext->ParamsFor.NotifyChangeDirectory.pNotificationBuffer;
|
||
|
||
*pTransactionOptions = RxDefaultTransactionOptions;
|
||
pTransactionOptions->NtTransactFunction = NT_TRANSACT_NOTIFY_CHANGE;
|
||
pTransactionOptions->TimeoutIntervalInMilliSeconds = PROXYCE_TRANSACTION_TIMEOUT_NOT_USED;
|
||
pTransactionOptions->Flags = PROXY_XACT_FLAGS_INDEFINITE_DELAY_IN_RESPONSE;
|
||
|
||
ProxyCeInitializeAsynchronousTransactionResumptionContext(
|
||
pResumptionContext,MRxProxyNotifyChangeDirectoryCompletion,pNotificationContext);
|
||
|
||
Status = ProxyCeAsynchronousTransact(
|
||
RxContext, // the RXContext for the transaction
|
||
pTransactionOptions, // transaction options
|
||
pNotifyRequest, // the setup buffer
|
||
sizeof(REQ_NOTIFY_CHANGE), // setup buffer length
|
||
pInputParamBuffer, // Input Param Buffer
|
||
InputParamBufferLength, // Input param buffer length
|
||
pOutputParamBuffer, // Output param buffer
|
||
OutputParamBufferLength, // output param buffer length
|
||
pInputDataBuffer, // Input data buffer
|
||
InputDataBufferLength, // Input data buffer length
|
||
pOutputDataBuffer, // output data buffer
|
||
OutputDataBufferLength, // output data buffer length
|
||
pResumptionContext // the resumption context
|
||
);
|
||
|
||
if (Status == STATUS_PENDING) {
|
||
PMRXPROXY_RX_CONTEXT pMRxProxyContext;
|
||
|
||
pMRxProxyContext = MRxProxyGetMinirdrContext(RxContext);
|
||
pMRxProxyContext->pCancelContext = pNotificationContext;
|
||
|
||
// Ensure that the appropriate cancel routine is set because this is a long term
|
||
// operation and the cancelling mechanism needs to be in place.
|
||
|
||
Status = RxSetMinirdrCancelRoutine(RxContext,MRxProxyNotifyChangeDirectoryCancellation);
|
||
if (Status == STATUS_SUCCESS) {
|
||
Status = STATUS_PENDING;
|
||
} else if (Status == STATUS_CANCELLED) {
|
||
MRxProxyNotifyChangeDirectoryCancellation(RxContext);
|
||
Status = STATUS_PENDING;
|
||
}
|
||
} else {
|
||
// On exit from this routine the request would have been completed in all
|
||
// the cases. The asynchronous case and synchronous case are folded into
|
||
// one async response by returning STATUS_PENDING.
|
||
|
||
Status = STATUS_PENDING;
|
||
}
|
||
} else {
|
||
NOTHING; //just return the status from the deferred open call
|
||
}
|
||
} else {
|
||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
#endif //0
|
||
|
||
Status = STATUS_NOT_SUPPORTED;
|
||
|
||
RxDbgTrace(-1, Dbg, ("MRxProxyNotifyChangeDirectory -> %08lx\n", Status ));
|
||
return Status;
|
||
}
|
||
|
||
NTSTATUS
|
||
MRxProxyFsControl(PRX_CONTEXT RxContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine handles all the FSCTL's
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
Notes:
|
||
|
||
Remoting of FSCTL's is permitted only to NT servers.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
|
||
RxCaptureFobx;
|
||
|
||
//PMRX_PROXY_SRV_OPEN pProxySrvOpen;
|
||
|
||
PLOWIO_CONTEXT pLowIoContext = &RxContext->LowIoContext;
|
||
ULONG FsControlCode = pLowIoContext->ParamsFor.FsCtl.FsControlCode;
|
||
|
||
|
||
PAGED_CODE();
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxProxyFsControl...Entry FsControlCode(%lx)\n", FsControlCode));
|
||
|
||
Status = STATUS_NOT_IMPLEMENTED;
|
||
RxDbgTrace(-1, Dbg, ("MRxProxyFsControl...Exit\n"));
|
||
return Status;
|
||
}
|
||
|
||
#if DBG
|
||
NTSTATUS
|
||
MRxProxyTestForLowIoIoctl(
|
||
IN PRX_CONTEXT RxContext
|
||
)
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
RxCaptureFcb;RxCaptureFobx;
|
||
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
||
PSZ Buffer = (PSZ)(LowIoContext->ParamsFor.IoCtl.pInputBuffer);
|
||
ULONG OutputBufferLength = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
|
||
ULONG InputBufferLength = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
|
||
UNICODE_STRING u;
|
||
PUNICODE_STRING FileName = &capFcb->AlreadyPrefixedName;
|
||
ULONG ReturnLength;
|
||
|
||
ReturnLength = OutputBufferLength;
|
||
if (ReturnLength > FileName->Length) {
|
||
ReturnLength = FileName->Length;
|
||
}
|
||
|
||
RxDbgTrace(0, Dbg,
|
||
("Here in MRxProxyTestForLowIoIoctl %s, obl = %08lx, rl=%08lx\n", Buffer, OutputBufferLength, ReturnLength));
|
||
|
||
//return an obvious string to make sure that darryl is copying the results out correctly
|
||
//BUGBUG need to check the lengths i.e. need outputl<=inputl; also need to check that count and buffer
|
||
// are aligned for wchar
|
||
|
||
RtlCopyMemory(Buffer,FileName->Buffer,ReturnLength);
|
||
u.Buffer = (PWCHAR)(Buffer);
|
||
u.Length = u.MaximumLength = (USHORT)ReturnLength;
|
||
RtlUpcaseUnicodeString(&u,&u,FALSE);
|
||
|
||
RxContext->InformationToReturn =
|
||
//LowIoContext->ParamsFor.IoCtl.OutputBufferLength =
|
||
ReturnLength;
|
||
|
||
return(Status);
|
||
}
|
||
#endif //if DBG
|
||
|
||
NTSTATUS
|
||
MRxProxyIoCtl(
|
||
IN OUT PRX_CONTEXT RxContext)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine performs an IOCTL operation. Currently, no calls are remoted; in fact, the only call accepted
|
||
is for debugging.
|
||
|
||
Arguments:
|
||
|
||
RxContext - the RDBSS context
|
||
|
||
Return Value:
|
||
|
||
RXSTATUS - The return status for the operation
|
||
|
||
Notes:
|
||
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
|
||
|
||
PLOWIO_CONTEXT pLowIoContext = &RxContext->LowIoContext;
|
||
ULONG IoControlCode = pLowIoContext->ParamsFor.IoCtl.IoControlCode;
|
||
|
||
RxDbgTrace(+1, Dbg, ("MRxProxyIoCtl...\n", 0));
|
||
RxDbgTrace( 0, Dbg, ("MRxProxyIoCtl = %08lx\n", IoControlCode));
|
||
|
||
switch (IoControlCode) {
|
||
#if DBG
|
||
case IOCTL_LMMR_TESTLOWIO:
|
||
Status = MRxProxyTestForLowIoIoctl(RxContext);
|
||
break;
|
||
#endif //if DBG
|
||
default:
|
||
break;
|
||
}
|
||
|
||
RxDbgTrace(-1, Dbg, ("MRxProxyIoCtl -> %08lx\n", Status ));
|
||
return Status;
|
||
}
|
||
|
||
|
||
|