You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
646 lines
22 KiB
646 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1989 - 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
devfcb.c
|
|
|
|
Abstract:
|
|
|
|
This module implements all the passthru stuff from the wrapper. currently
|
|
there is only one such function:
|
|
statistics
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
#include "smbmrx.h"
|
|
|
|
|
|
//
|
|
// Forward declarations.
|
|
//
|
|
|
|
NTSTATUS
|
|
MRxSmbCreateConnection (
|
|
IN PRX_CONTEXT RxContext,
|
|
OUT PBOOLEAN PostToFsp
|
|
);
|
|
|
|
NTSTATUS
|
|
MRxSmbDeleteConnection (
|
|
IN PRX_CONTEXT RxContext,
|
|
OUT PBOOLEAN PostToFsp
|
|
);
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, MRxSmbGetStatistics)
|
|
#pragma alloc_text(PAGE, MRxSmbDevFcbXXXControlFile)
|
|
#endif
|
|
|
|
//
|
|
// The local trace mask for this part of the module
|
|
//
|
|
|
|
#define Dbg (DEBUG_TRACE_DEVFCB)
|
|
|
|
MRX_SMB_STATISTICS MRxSmbStatistics;
|
|
|
|
NTSTATUS
|
|
MRxSmbGetStatistics(
|
|
IN OUT PRX_CONTEXT RxContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine gathers the statistics from the mini redirector
|
|
|
|
Arguments:
|
|
|
|
RxContext - Describes the Fsctl and Context.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS -- the Startup sequence was successfully completed.
|
|
|
|
any other value indicates the appropriate error.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
{
|
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|
|
|
PMRX_SMB_STATISTICS pStatistics;
|
|
ULONG BufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
|
|
|
|
PAGED_CODE();
|
|
|
|
pStatistics = (PMRX_SMB_STATISTICS)(LowIoContext->ParamsFor.FsCtl.pOutputBuffer);
|
|
|
|
if (BufferLength < sizeof(MRX_SMB_STATISTICS)) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
RxContext->InformationToReturn = sizeof(MRX_SMB_STATISTICS);
|
|
MRxSmbStatistics.SmbsReceived.QuadPart++;
|
|
|
|
//some stuff we have to copy from the device object......
|
|
MRxSmbStatistics.PagingReadBytesRequested = MRxSmbDeviceObject->PagingReadBytesRequested;
|
|
MRxSmbStatistics.NonPagingReadBytesRequested = MRxSmbDeviceObject->NonPagingReadBytesRequested;
|
|
MRxSmbStatistics.CacheReadBytesRequested = MRxSmbDeviceObject->CacheReadBytesRequested;
|
|
MRxSmbStatistics.NetworkReadBytesRequested = MRxSmbDeviceObject->NetworkReadBytesRequested;
|
|
MRxSmbStatistics.PagingWriteBytesRequested = MRxSmbDeviceObject->PagingWriteBytesRequested;
|
|
MRxSmbStatistics.NonPagingWriteBytesRequested = MRxSmbDeviceObject->NonPagingWriteBytesRequested;
|
|
MRxSmbStatistics.CacheWriteBytesRequested = MRxSmbDeviceObject->CacheWriteBytesRequested;
|
|
MRxSmbStatistics.NetworkWriteBytesRequested = MRxSmbDeviceObject->NetworkWriteBytesRequested;
|
|
MRxSmbStatistics.ReadOperations = MRxSmbDeviceObject->ReadOperations;
|
|
MRxSmbStatistics.RandomReadOperations = MRxSmbDeviceObject->RandomReadOperations;
|
|
MRxSmbStatistics.WriteOperations = MRxSmbDeviceObject->WriteOperations;
|
|
MRxSmbStatistics.RandomWriteOperations = MRxSmbDeviceObject->RandomWriteOperations;
|
|
|
|
MRxSmbStatistics.LargeReadSmbs = MRxSmbStatistics.ReadSmbs - MRxSmbStatistics.SmallReadSmbs;
|
|
MRxSmbStatistics.LargeWriteSmbs = MRxSmbStatistics.WriteSmbs - MRxSmbStatistics.SmallWriteSmbs;
|
|
|
|
MRxSmbStatistics.CurrentCommands = SmbCeStartStopContext.ActiveExchanges;
|
|
|
|
*pStatistics = MRxSmbStatistics;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
MRxSmbDevFcbXXXControlFile (
|
|
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:
|
|
|
|
STATUS_SUCCESS -- the Startup sequence was successfully completed.
|
|
|
|
any other value indicates the appropriate error in the startup sequence.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status;
|
|
RxCaptureFobx;
|
|
UCHAR MajorFunctionCode = RxContext->MajorFunction;
|
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|
ULONG ControlCode = LowIoContext->ParamsFor.FsCtl.FsControlCode;
|
|
|
|
PAGED_CODE();
|
|
|
|
RxDbgTrace(+1, Dbg, ("MRxSmbDevFcb\n"));
|
|
switch (MajorFunctionCode) {
|
|
case IRP_MJ_FILE_SYSTEM_CONTROL:
|
|
{
|
|
switch (LowIoContext->ParamsFor.FsCtl.MinorFunction) {
|
|
case IRP_MN_USER_FS_REQUEST:
|
|
{
|
|
RxDbgTrace(-1, Dbg, ("RxCommonDevFCBFsCtl -> unimplemented fsctl\n"));
|
|
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) {
|
|
|
|
case IOCTL_SMBMRX_ADDCONN:
|
|
DbgPrint("Processing Create Connection IOCTL\n");
|
|
Status = MRxSmbCreateConnection( RxContext, &RxContext->PostRequest );
|
|
break;
|
|
|
|
case IOCTL_SMBMRX_DELCONN:
|
|
DbgPrint("Processing Delete Connection IOCTL\n");
|
|
Status = MRxSmbDeleteConnection( RxContext, &RxContext->PostRequest );
|
|
break;
|
|
|
|
case IOCTL_SMBMRX_GETSTATE:
|
|
{
|
|
ULONG OutBufferLength = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
|
|
PBYTE OutBuffer = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
|
|
ULONG CurrentState = RDR_NULL_STATE;
|
|
|
|
if ( OutBufferLength >= sizeof(ULONG) )
|
|
{
|
|
// map the states to control app's equivalents
|
|
switch ( MRxSmbState )
|
|
{
|
|
case MRXSMB_STARTABLE:
|
|
case MRXSMB_STOPPED:
|
|
CurrentState = RDR_STOPPED;
|
|
break;
|
|
case MRXSMB_START_IN_PROGRESS:
|
|
CurrentState = RDR_STARTING;
|
|
break;
|
|
case MRXSMB_STARTED:
|
|
CurrentState = RDR_STARTED;
|
|
break;
|
|
}
|
|
*(ULONG *)OutBuffer = CurrentState;
|
|
RxContext->InformationToReturn = sizeof(ULONG);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IOCTL_SMBMRX_START:
|
|
switch (MRxSmbState) {
|
|
|
|
case MRXSMB_STARTABLE:
|
|
// The correct sequence of start events issued by the workstation
|
|
// service would have avoided this. We can recover from this
|
|
// by actually invoking RxStartMiniRdr.
|
|
|
|
if (capFobx) {
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
goto FINALLY;
|
|
}
|
|
|
|
(MRXSMB_STATE)InterlockedCompareExchange(
|
|
(PLONG)&MRxSmbState,
|
|
MRXSMB_START_IN_PROGRESS,
|
|
MRXSMB_STARTABLE);
|
|
//lack of break is intentional
|
|
|
|
case MRXSMB_START_IN_PROGRESS:
|
|
{
|
|
Status = RxStartMinirdr(RxContext,&RxContext->PostRequest);
|
|
|
|
if (Status == STATUS_REDIRECTOR_STARTED) {
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else if ( Status == STATUS_PENDING && RxContext->PostRequest == TRUE )
|
|
{
|
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MRXSMB_STARTED:
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
|
|
default:
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IOCTL_SMBMRX_STOP:
|
|
if (capFobx) {
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
goto FINALLY;
|
|
}
|
|
|
|
|
|
if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0) {
|
|
return STATUS_REDIRECTOR_HAS_OPEN_HANDLES;
|
|
} else {
|
|
MRXSMB_STATE CurrentState;
|
|
|
|
CurrentState = (MRXSMB_STATE)
|
|
InterlockedCompareExchange(
|
|
(PLONG)&MRxSmbState,
|
|
MRXSMB_STARTABLE,
|
|
MRXSMB_STARTED);
|
|
|
|
Status = RxStopMinirdr(
|
|
RxContext,
|
|
&RxContext->PostRequest );
|
|
if ( Status == STATUS_PENDING && RxContext->PostRequest == TRUE )
|
|
{
|
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default :
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
} // end of switch
|
|
} //end of IOCTL cases
|
|
break;
|
|
default:
|
|
ASSERT(!"unimplemented major function");
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
}
|
|
|
|
FINALLY:
|
|
RxDbgTrace(
|
|
-1,
|
|
Dbg,
|
|
("MRxSmbDevFcb st,info=%08lx,%08lx\n",
|
|
Status,
|
|
RxContext->InformationToReturn));
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
// for ea testing
|
|
ULONG BuildCustomEAData( PVOID EaPtr )
|
|
{
|
|
PFILE_FULL_EA_INFORMATION thisEa = (PFILE_FULL_EA_INFORMATION) EaPtr;
|
|
PBYTE valuePtr;
|
|
|
|
// Set the user name EA
|
|
thisEa->Flags = 0;
|
|
thisEa->EaNameLength = sizeof("UserName");
|
|
RtlCopyMemory( thisEa->EaName, "UserName\0", thisEa->EaNameLength + 1 );
|
|
valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
|
|
//thisEa->EaNameLength--; // don't include the null in the EaName length
|
|
thisEa->EaValueLength = sizeof(L"TestUser");
|
|
RtlCopyMemory( valuePtr, L"TestUser", thisEa->EaValueLength );
|
|
thisEa->NextEntryOffset = ((PBYTE) valuePtr + thisEa->EaValueLength ) -
|
|
(PBYTE) thisEa;
|
|
|
|
// Set the password EA
|
|
thisEa = (PFILE_FULL_EA_INFORMATION) ((PBYTE) thisEa + thisEa->NextEntryOffset);
|
|
|
|
thisEa->Flags = 0;
|
|
thisEa->EaNameLength = sizeof("Password");
|
|
RtlCopyMemory( thisEa->EaName, "Password\0", thisEa->EaNameLength + 1 );
|
|
valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
|
|
//thisEa->EaNameLength--; // don't include the null in the EaName length
|
|
thisEa->EaValueLength = sizeof(WCHAR);
|
|
RtlCopyMemory( valuePtr, L"\0", thisEa->EaValueLength );
|
|
thisEa->NextEntryOffset = ((PBYTE) valuePtr + thisEa->EaValueLength ) -
|
|
(PBYTE) thisEa;
|
|
|
|
// Set the domain EA
|
|
thisEa = (PFILE_FULL_EA_INFORMATION) ((PBYTE) thisEa + thisEa->NextEntryOffset);
|
|
|
|
thisEa->Flags = 0;
|
|
thisEa->EaNameLength = sizeof("Domain");
|
|
RtlCopyMemory( thisEa->EaName, "Domain\0", thisEa->EaNameLength + 1 );
|
|
valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
|
|
//thisEa->EaNameLength--; // don't include the null in the EaName length
|
|
thisEa->EaValueLength = sizeof(L"WORKGROUP");
|
|
RtlCopyMemory( valuePtr, L"WORKGROUP", thisEa->EaValueLength );
|
|
thisEa->NextEntryOffset = 0;
|
|
|
|
return ((PBYTE) valuePtr + thisEa->EaValueLength) - (PBYTE) EaPtr;
|
|
}
|
|
#endif
|
|
|
|
NTSTATUS
|
|
GetConnectionHandle(
|
|
IN PUNICODE_STRING ConnectionName,
|
|
PVOID EaBuffer,
|
|
ULONG EaLength,
|
|
PHANDLE Handle )
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING FileName;
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
ConnectionName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = ZwCreateFile(
|
|
Handle,
|
|
SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
FILE_OPEN_IF,
|
|
FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
|
|
EaBuffer,
|
|
EaLength);
|
|
|
|
DbgPrint("ZwCreateFile returned %lx\n",Status);
|
|
|
|
if ( Status == STATUS_SUCCESS )
|
|
{
|
|
if ( *Handle != INVALID_HANDLE_VALUE ){
|
|
DbgPrint("ZwCreateFile returned success\n");
|
|
} else {
|
|
DbgPrint("ZwCreateFile failed\n");
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MRxSmbCreateConnection (
|
|
IN PRX_CONTEXT RxContext,
|
|
OUT PBOOLEAN PostToFsp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
IN PRX_CONTEXT RxContext - Describes the Fsctl and Context
|
|
|
|
Return Value:
|
|
|
|
RXSTATUS
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|
|
|
ULONG InBufferLength = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
|
|
PBYTE InBuffer = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
|
|
|
|
BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
|
|
BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
|
|
|
|
PAGED_CODE();
|
|
|
|
RxDbgTrace(+1, Dbg, ("MRxSmbCreateConnection - entry\n"));
|
|
|
|
if (!Wait) {
|
|
//just post right now!
|
|
*PostToFsp = TRUE;
|
|
return(STATUS_PENDING);
|
|
}
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
try {
|
|
PSMBMRX_CONNECTINFO ConnectInfo;
|
|
UNICODE_STRING ConnectionName;
|
|
PBYTE EaBuffer;
|
|
ULONG EaLength;
|
|
ULONG Validator;
|
|
ULONG CompareLength;
|
|
HANDLE Handle;
|
|
|
|
if ( InBufferLength >= sizeof( PSMBMRX_CONNECTINFO ) )
|
|
{
|
|
ConnectInfo = (PSMBMRX_CONNECTINFO) InBuffer;
|
|
if (((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->ConnectionNameOffset +
|
|
(USHORT)ConnectInfo->ConnectionNameLength <= InBufferLength) &&
|
|
((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->EaDataOffset +
|
|
(USHORT)ConnectInfo->EaDataLength <= InBufferLength))
|
|
{
|
|
ConnectionName.Buffer = (PWCHAR) ((PBYTE) ConnectInfo->InfoArea +
|
|
ConnectInfo->ConnectionNameOffset);
|
|
ConnectionName.Length = (USHORT) ConnectInfo->ConnectionNameLength;
|
|
ConnectionName.MaximumLength = (USHORT) ConnectInfo->ConnectionNameLength;
|
|
|
|
EaLength = ConnectInfo->EaDataLength;
|
|
EaBuffer = ( EaLength > 0 ) ?
|
|
ConnectInfo->InfoArea + ConnectInfo->EaDataOffset : NULL;
|
|
// Validate the connection name. The name must start with our device name.
|
|
// We can't allow a create on some rogue pathname outside our device
|
|
CompareLength = sizeof(DD_SMBMRX_FS_DEVICE_NAME_U);
|
|
CompareLength -= ( CompareLength > 0 ) ? sizeof(WCHAR) : 0;
|
|
CompareLength = min( CompareLength, ConnectionName.Length );
|
|
Validator = (ULONG) RtlCompareMemory( ConnectionName.Buffer, DD_SMBMRX_FS_DEVICE_NAME_U,
|
|
CompareLength );
|
|
|
|
if ( Validator == CompareLength )
|
|
{
|
|
Status = GetConnectionHandle( &ConnectionName, EaBuffer, EaLength, &Handle );
|
|
if ( Status == STATUS_SUCCESS )
|
|
{
|
|
if ( Handle != INVALID_HANDLE_VALUE )
|
|
{
|
|
ZwClose( Handle );
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_BAD_NETWORK_NAME;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_OBJECT_PATH_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
|
|
try_return(Status);
|
|
|
|
try_exit:NOTHING;
|
|
|
|
} finally {
|
|
RxDbgTrace(0, Dbg, ("MRxSmbCreateConnection - exit Status = %08lx\n", Status));
|
|
RxDbgTraceUnIndent(-1,Dbg);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MRxSmbDeleteConnection (
|
|
IN PRX_CONTEXT RxContext,
|
|
OUT PBOOLEAN PostToFsp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
IN PRX_CONTEXT RxContext - Describes the Fsctl and Context
|
|
|
|
Return Value:
|
|
|
|
RXSTATUS
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
|
|
|
|
ULONG InBufferLength = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
|
|
PBYTE InBuffer = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
|
|
|
|
BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
|
|
BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
|
|
|
|
PV_NET_ROOT VNetRoot;
|
|
PFILE_OBJECT pFileObject;
|
|
|
|
PAGED_CODE();
|
|
|
|
RxDbgTrace(+1, Dbg, ("MRxSmbDeleteConnection - entry\n"));
|
|
|
|
if (!Wait) {
|
|
//just post right now!
|
|
*PostToFsp = TRUE;
|
|
return(STATUS_PENDING);
|
|
}
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
try {
|
|
PSMBMRX_CONNECTINFO ConnectInfo;
|
|
UNICODE_STRING ConnectionName;
|
|
PBYTE EaBuffer;
|
|
ULONG EaLength;
|
|
ULONG Validator;
|
|
ULONG CompareLength;
|
|
HANDLE Handle;
|
|
|
|
if ( InBufferLength >= sizeof( PSMBMRX_CONNECTINFO ) )
|
|
{
|
|
ConnectInfo = (PSMBMRX_CONNECTINFO) InBuffer;
|
|
|
|
if (((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->ConnectionNameOffset +
|
|
(USHORT)ConnectInfo->ConnectionNameLength <= InBufferLength) &&
|
|
((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->EaDataOffset +
|
|
(USHORT)ConnectInfo->EaDataLength <= InBufferLength))
|
|
{
|
|
ConnectionName.Buffer = (PWCHAR) ((PBYTE) ConnectInfo->InfoArea +
|
|
ConnectInfo->ConnectionNameOffset);
|
|
ConnectionName.Length = (USHORT) ConnectInfo->ConnectionNameLength;
|
|
ConnectionName.MaximumLength = (USHORT) ConnectInfo->ConnectionNameLength;
|
|
|
|
EaLength = ConnectInfo->EaDataLength;
|
|
EaBuffer = ( EaLength > 0 ) ?
|
|
ConnectInfo->InfoArea + ConnectInfo->EaDataOffset : NULL;
|
|
// Validate the connection name. The name must start with our device name.
|
|
// We can't allow a create on some rogue pathname outside our device
|
|
CompareLength = sizeof(DD_SMBMRX_FS_DEVICE_NAME_U);
|
|
CompareLength -= ( CompareLength > 0 ) ? sizeof(WCHAR) : 0;
|
|
CompareLength = min( CompareLength, ConnectionName.Length );
|
|
Validator = (ULONG) RtlCompareMemory( ConnectionName.Buffer, DD_SMBMRX_FS_DEVICE_NAME_U,
|
|
CompareLength );
|
|
|
|
if ( Validator == CompareLength )
|
|
{
|
|
Status = GetConnectionHandle( &ConnectionName, EaBuffer, EaLength, &Handle );
|
|
if ( Status == STATUS_SUCCESS )
|
|
{
|
|
if ( Handle != INVALID_HANDLE_VALUE )
|
|
{
|
|
Status = ObReferenceObjectByHandle( Handle,
|
|
0L,
|
|
NULL,
|
|
KernelMode,
|
|
(PVOID *)&pFileObject,
|
|
NULL );
|
|
if ( NT_SUCCESS(Status) )
|
|
{
|
|
// VNetRoot exists as FOBx in the FsContext2
|
|
VNetRoot = (PV_NET_ROOT) pFileObject->FsContext2;
|
|
// make sure the node looks right
|
|
if (NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT)
|
|
{
|
|
RxDbgTrace(-1, Dbg, ("MRxSmbDeleteConnection - Calling RxFinalizeConnection"));
|
|
Status = RxFinalizeConnection(VNetRoot->NetRoot, VNetRoot, TRUE);
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_BAD_NETWORK_NAME;
|
|
}
|
|
ObDereferenceObject(pFileObject);
|
|
}
|
|
ZwClose(Handle);
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_BAD_NETWORK_NAME;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status =STATUS_OBJECT_PATH_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
|
|
try_return(Status);
|
|
|
|
try_exit:NOTHING;
|
|
|
|
} finally {
|
|
RxDbgTrace(0, Dbg, ("MRxSmbDeleteConnection - exit Status = %08lx\n", Status));
|
|
RxDbgTraceUnIndent(-1,Dbg);
|
|
}
|
|
|
|
return Status;
|
|
}
|