NT4/private/ntos/mup/fscontrl.c
2020-09-30 17:12:29 +02:00

353 lines
8.0 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
fscontrl.c
Abstract:
This module implements the file system control routines for the MUP
called by the dispatch driver.
Author:
Manny Weiser (mannyw) 26-Dec-1991
Revision History:
--*/
#include "mup.h"
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_FSCONTROL)
//
// local procedure prototypes
//
NTSTATUS
RegisterUncProvider (
IN PMUP_DEVICE_OBJECT MupDeviceObject,
IN PIRP Irp
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, MupFsControl )
#pragma alloc_text( PAGE, RegisterUncProvider )
#endif
NTSTATUS
MupFsControl (
IN PMUP_DEVICE_OBJECT MupDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine implements the the File System Control IRP.
Arguments:
MupDeviceObject - Supplies the device object to use.
Irp - Supplies the Irp being processed
Return Value:
NTSTATUS - The status for the Irp
--*/
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
PAGED_CODE();
DebugTrace(+1, Dbg, "MupFsControl\n", 0);
//
// Reference our input parameters to make things easier
//
irpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace(+1, Dbg, "MupFileSystemControl\n", 0);
DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp);
DebugTrace( 0, Dbg, "OutputBufferLength = %08lx\n", irpSp->Parameters.FileSystemControl.OutputBufferLength);
DebugTrace( 0, Dbg, "InputBufferLength = %08lx\n", irpSp->Parameters.FileSystemControl.InputBufferLength);
DebugTrace( 0, Dbg, "FsControlCode = %08lx\n", irpSp->Parameters.FileSystemControl.FsControlCode);
try {
//
// Decide how to handle this IRP. Call the appropriate worker function.
//
switch (irpSp->Parameters.FileSystemControl.FsControlCode) {
case FSCTL_MUP_REGISTER_UNC_PROVIDER:
status = RegisterUncProvider( MupDeviceObject, Irp );
break;
default:
if (MupEnableDfs) {
status = DfsFsdFileSystemControl(
(PDEVICE_OBJECT) MupDeviceObject,
Irp);
} else {
status = STATUS_INVALID_PARAMETER;
MupCompleteRequest(Irp, STATUS_INVALID_PARAMETER);
}
}
} except ( EXCEPTION_EXECUTE_HANDLER ) {
NOTHING;
}
//
// Return to the caller.
//
DebugTrace(-1, Dbg, "MupFsControl -> %08lx\n", status);
return status;
}
NTSTATUS
RegisterUncProvider (
IN PMUP_DEVICE_OBJECT MupDeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This function handles registration of a UNC provider. The provider
is added to the list of available providers.
Arguments:
MupDeviceObject - A pointer to the file system device object.
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - the return status for the operation
--*/
{
NTSTATUS status;
PVCB vcb;
PVOID fsContext2;
PIO_STACK_LOCATION irpSp;
PREDIRECTOR_REGISTRATION paramBuffer;
ULONG paramLength;
BLOCK_TYPE blockType;
PUNC_PROVIDER uncProvider;
PVOID dataBuffer;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_HANDLE_INFORMATION handleInformation;
MupDeviceObject;
PAGED_CODE();
irpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace(+1, Dbg, "RegisterUncProvider\n", 0);
//
// Get MUP ordering information, if we haven't already.
//
MupAcquireGlobalLock();
if ( !MupOrderInitialized ) {
MupOrderInitialized = TRUE;
MupReleaseGlobalLock();
MupGetProviderInformation();
} else {
MupReleaseGlobalLock();
}
//
// Make local copies of the input parameters to make things easier.
//
paramLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
paramBuffer = Irp->AssociatedIrp.SystemBuffer;
//
// Decode the file object. If it is the file system VCB, it will be
// referenced.
//
blockType = MupDecodeFileObject(
irpSp->FileObject,
(PVOID *)&vcb,
&fsContext2
);
if ( blockType != BlockTypeVcb ) {
DebugTrace(0, Dbg, "File is disconnected from us\n", 0);
MupCompleteRequest( Irp, STATUS_INVALID_HANDLE );
status = STATUS_INVALID_HANDLE;
DebugTrace(-1, Dbg, "RegisterUncProvider -> %08lx\n", status );
return status;
}
try {
UNICODE_STRING deviceName;
deviceName.Length = (USHORT)paramBuffer->DeviceNameLength;
deviceName.MaximumLength = (USHORT)paramBuffer->DeviceNameLength;
deviceName.Buffer = (PWCH)((PCHAR)paramBuffer + paramBuffer->DeviceNameOffset);
//
// Do the work
//
uncProvider = MupCheckForUnregisteredProvider( &deviceName );
if ( uncProvider == NULL) {
uncProvider = MupAllocateUncProvider(
paramBuffer->DeviceNameLength
);
//
// Copy the data from the IRP.
//
dataBuffer = uncProvider + 1;
uncProvider->DeviceName = deviceName;
uncProvider->DeviceName.Buffer = dataBuffer;
uncProvider->Priority = 0x7FFFFFFF;
RtlMoveMemory(
uncProvider->DeviceName.Buffer,
(PCHAR)paramBuffer + paramBuffer->DeviceNameOffset,
paramBuffer->DeviceNameLength
);
}
dataBuffer = (PCHAR)dataBuffer + uncProvider->DeviceName.MaximumLength;
uncProvider->MailslotsSupported = paramBuffer->MailslotsSupported;
//
// Use the file object, to keep a pointer to the uncProvider
//
MupReferenceBlock( uncProvider );
irpSp->FileObject->FsContext2 = uncProvider;
//
// Get a handle to the provider.
//
InitializeObjectAttributes(
&objectAttributes,
&uncProvider->DeviceName,
OBJ_CASE_INSENSITIVE, // Attributes
0, // Root Directory
NULL // Security
);
status = NtOpenFile(
&uncProvider->Handle,
FILE_TRAVERSE,
&objectAttributes,
&ioStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_DIRECTORY_FILE
);
if ( NT_SUCCESS( status ) ) {
status = ioStatusBlock.Status;
}
if ( !NT_SUCCESS( status ) ) {
MupCompleteRequest( Irp, status );
} else {
MupAcquireGlobalLock();
MupProviderCount++;
InsertTailList( &MupProviderList, &uncProvider->ListEntry );
MupReleaseGlobalLock();
status = ObReferenceObjectByHandle(
uncProvider->Handle,
0,
NULL,
KernelMode,
(PVOID *)&uncProvider->FileObject,
&handleInformation
);
ASSERT( NT_SUCCESS( status ) );
uncProvider->DeviceObject = IoGetRelatedDeviceObject(
uncProvider->FileObject
);
//
// !!! What do we do with the handle? It is useless.
//
//
// Finish up the fs control IRP.
//
status = STATUS_SUCCESS;
MupCompleteRequest( Irp, status );
}
} finally {
if ( AbnormalTermination() ) {
status = STATUS_INVALID_USER_BUFFER;
}
//
// Release the reference to the VCB.
//
MupDereferenceVcb( vcb );
DebugTrace(-1, Dbg, "MupRegisterUncProvider -> %08lx\n", status);
}
return status;
}