267 lines
6.8 KiB
Plaintext
267 lines
6.8 KiB
Plaintext
//+----------------------------------------------------------------------------
|
||
//
|
||
// Copyright (C) 1996, Microsoft Corporation
|
||
//
|
||
// File: create.c
|
||
//
|
||
// Contents: Implements the Create code for the Dfs server. The Dfs server
|
||
// only allows opening the File System Device object for the
|
||
// express purpose of FsControlling to the Dfs server.
|
||
//
|
||
// Classes:
|
||
//
|
||
// Functions: DfsFsdCreate
|
||
// DfsOpenDevice
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
#include "dfsprocs.h"
|
||
#include "attach.h"
|
||
|
||
//
|
||
// The debug trace level
|
||
//
|
||
|
||
#define Dbg (DEBUG_TRACE_CREATE)
|
||
|
||
//
|
||
// Local procedure prototypes
|
||
//
|
||
|
||
NTSTATUS
|
||
DfsOpenDevice (
|
||
IN PFILE_OBJECT FileObject,
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN ULONG CreateOptions);
|
||
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
|
||
#pragma alloc_text( PAGE, DfsFsdCreate )
|
||
#pragma alloc_text( PAGE, DfsOpenDevice )
|
||
|
||
#endif // ALLOC_PRAGMA
|
||
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsFsdCreate, public
|
||
//
|
||
// Synopsis: This routine implements the FSD part of the NtCreateFile
|
||
// and NtOpenFile API calls.
|
||
//
|
||
// Arguments: [DeviceObject] -- Supplies the device object relative to which
|
||
// the open is to be processed.
|
||
// [Irp] - Supplies the Irp being processed.
|
||
//
|
||
// Returns: NTSTATUS - The Fsd status for the Irp
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
DfsFsdCreate (
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
)
|
||
{
|
||
NTSTATUS status;
|
||
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
|
||
PFILE_OBJECT fileObject;
|
||
ULONG createOptions;
|
||
|
||
DebugTrace(+1, Dbg, "DfsFsdCreate: Entered\n", 0);
|
||
|
||
ASSERT(IoIsOperationSynchronous(Irp) == TRUE);
|
||
|
||
//
|
||
// If someone is coming in via a device object attached to a file system
|
||
// device object, pass it through.
|
||
//
|
||
|
||
if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) {
|
||
|
||
status = DfsVolumePassThrough(DeviceObject, Irp);
|
||
|
||
DebugTrace(-1, Dbg, "DfsFsdCreate: FS Device Pass Through Exit %08lx\n", status);
|
||
|
||
return status;
|
||
|
||
}
|
||
|
||
//
|
||
// If someone is coming in via a device object attached to a file system
|
||
// volume, we need to see if they are opening an exit point via its local
|
||
// file system name.
|
||
//
|
||
|
||
if (DeviceObject->DeviceType == FILE_DEVICE_DFS_VOLUME) {
|
||
|
||
status = DfsOpenFile(DeviceObject, Irp);
|
||
|
||
DebugTrace(-1, Dbg, "DfsFsdCreate: Local File Open Exit %08lx\n', status);
|
||
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// The only other create we handle is someone trying to open our own
|
||
// file system device object.
|
||
//
|
||
|
||
ASSERT(DeviceObject->DeviceType == FILE_DEVICE_DFS_FILE_SYSTEM);
|
||
|
||
FsRtlEnterFileSystem();
|
||
|
||
fileObject = irpSp->FileObject;
|
||
createOptions = irpSp->Parameters.Create.Options;
|
||
|
||
if (fileObject->FileName.Length == 0 &&
|
||
fileObject->RelatedFileObject == NULL) {
|
||
|
||
//
|
||
// This is the only case we handle
|
||
//
|
||
|
||
status = DfsOpenDevice(
|
||
fileObject,
|
||
DeviceObject,
|
||
createOptions);
|
||
|
||
} else {
|
||
|
||
status = STATUS_INVALID_DEVICE_REQUEST;
|
||
|
||
}
|
||
|
||
FsRtlExitFileSystem();
|
||
|
||
//
|
||
// And return to our caller
|
||
//
|
||
|
||
DebugTrace(-1, Dbg, "DfsFsdCreate: Exit -> %08lx\n", status );
|
||
|
||
DfsCompleteRequest( Irp, status );
|
||
|
||
return status;
|
||
}
|
||
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsOpenFile, local
|
||
//
|
||
// Synopsis: This routine handles file opens that come in via attached
|
||
// volumes. The semantics of this open are:
|
||
//
|
||
// If the named file is a child of a DfsExitPath, fail it
|
||
// with access denied.
|
||
//
|
||
// If the named file is a DfsExitPath, and CreateOptions specify
|
||
// DELETE_ON_CLOSE, fail it with access denied.
|
||
//
|
||
// In all other cases, allocate an FCB, and pass the open through
|
||
// to the underlying FS. If the open succeeds, then insert the
|
||
// FCB in our FCB table. If the open fails, destroy the FCB.
|
||
//
|
||
// Arguments: [DeviceObject] -- The attached device object through which
|
||
// the Create Irp came in.
|
||
//
|
||
// [Irp] -- The Create Irp.
|
||
//
|
||
// Returns: [STATUS_INSUFFICIENT_RESOURCES] -- Unable to allocate an FCB.
|
||
//
|
||
// [STATUS_ACCESS_DENIED] -- The file is a child of a Dfs exit
|
||
// path or the file is a Dfs exit path and
|
||
// DELETE_ON_CLOSE was specified.
|
||
//
|
||
// Status from the underlying FS.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
DfsOpenFile(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp)
|
||
{
|
||
NTSTATUS status;
|
||
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
|
||
PFILE_OBJECT fileObject = irpSp->FileObject;
|
||
ULONG createOptions = irpSp->Parameters.Create.Options;
|
||
|
||
DebugTrace(+1, Dbg, "DfsOpenFile - Entered\n", 0);
|
||
|
||
if (fileObject->RelatedFileObject) {
|
||
|
||
DebugTrace(0,
|
||
}
|
||
}
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsOpenDevice, local
|
||
//
|
||
// Synopsis: This routine opens the specified device for direct
|
||
// access.
|
||
//
|
||
// Arguments: [FileObject] - Supplies the File object
|
||
// [DeviceObject] - Supplies the object denoting the device
|
||
// being opened
|
||
// [CreateOptions] - Supplies the create options for
|
||
// this operation
|
||
//
|
||
// Returns: [IO_STATUS_BLOCK] - Returns the completion status for
|
||
// the operation
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
DfsOpenDevice (
|
||
IN PFILE_OBJECT FileObject,
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN ULONG CreateOptions
|
||
) {
|
||
|
||
//
|
||
// Check to see which type of device is being opened.
|
||
// We don't permit all open modes on the file system
|
||
// device object.
|
||
//
|
||
|
||
ULONG CreateDisposition = (CreateOptions >> 24) & 0x000000ff;
|
||
|
||
//
|
||
// Check for proper desired access and rights
|
||
//
|
||
|
||
if (CreateDisposition != FILE_OPEN
|
||
&& CreateDisposition != FILE_OPEN_IF ) {
|
||
|
||
DebugTrace(0, Dbg,
|
||
"DfsOpenDevice: Invalid CreateDisposition\n", 0);
|
||
|
||
return( STATUS_ACCESS_DENIED );
|
||
}
|
||
|
||
//
|
||
// Check if we were to open a directory
|
||
//
|
||
|
||
if (CreateOptions & FILE_DIRECTORY_FILE) {
|
||
|
||
DebugTrace(0, Dbg,
|
||
"DfsOpenDevice: Cannot open device as a directory\n", 0);
|
||
|
||
return( STATUS_NOT_A_DIRECTORY );
|
||
|
||
}
|
||
|
||
FileObject->FsContext = (PVOID) DFS_OPEN_CONTEXT;
|
||
|
||
return( STATUS_SUCCESS );
|
||
}
|
||
|
||
|