451 lines
11 KiB
C
451 lines
11 KiB
C
//+----------------------------------------------------------------------------
|
||
//
|
||
// Copyright (C) 1992, Microsoft Corporation.
|
||
//
|
||
// File: STRUCSUP.C
|
||
//
|
||
// Contents: This module implements the Dsfs in-memory data structure
|
||
// manipulation routines
|
||
//
|
||
// Functions:
|
||
// DfsCreateIrpContext -
|
||
// DfsDeleteIrpContext_Real -
|
||
// DfsInitializeVcb -
|
||
// DfsCreateFcb -
|
||
// DfsDeleteFcb_Real -
|
||
// DspAllocateStringRoutine -
|
||
//
|
||
// History: 12 Nov 1991 AlanW Created from CDFS souce.
|
||
// 8 May 1992 PeterCo added support for new PKT stuff (M000)
|
||
//-----------------------------------------------------------------------------
|
||
|
||
|
||
#include "dfsprocs.h"
|
||
|
||
//
|
||
// The debug trace level
|
||
//
|
||
|
||
#define Dbg (DEBUG_TRACE_STRUCSUP)
|
||
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text( PAGE, DfsInitializeVcb )
|
||
#pragma alloc_text( PAGE, DfsDeleteIrpContext_Real)
|
||
#pragma alloc_text( PAGE, DfsCreateFcb )
|
||
#pragma alloc_text( PAGE, DfsDeleteFcb_Real )
|
||
|
||
//
|
||
// The following routines cannot be paged because they acquire/release
|
||
// spin locks
|
||
//
|
||
// DfsCreateIrpContext
|
||
// DfsDeleteIrpContext_Real
|
||
//
|
||
|
||
#endif // ALLOC_PRAGMA
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsCreateIrpContext, public
|
||
//
|
||
// Synopsis: This routine creates a new IRP_CONTEXT record
|
||
//
|
||
// Arguments: [Irp] - Supplies the originating Irp.
|
||
// [Wait] - Supplies the wait value to store in the context
|
||
//
|
||
// Returns: PIRP_CONTEXT - returns a pointer to the newly allocate
|
||
// IRP_CONTEXT Record
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
PIRP_CONTEXT
|
||
DfsCreateIrpContext (
|
||
IN PIRP Irp,
|
||
IN BOOLEAN Wait
|
||
) {
|
||
KIRQL SavedIrql;
|
||
PIRP_CONTEXT IrpContext;
|
||
PIO_STACK_LOCATION IrpSp;
|
||
|
||
DfsDbgTrace(+1, Dbg, "DfsCreateIrpContext\n", 0);
|
||
|
||
IrpContext = ExAllocateFromNPagedLookasideList (&DfsData.IrpContextLookaside);
|
||
|
||
if (IrpContext != NULL) {
|
||
//
|
||
// Zero out the irp context and indicate that it is from pool and
|
||
// not zone allocated
|
||
//
|
||
|
||
RtlZeroMemory( IrpContext, sizeof(IRP_CONTEXT) );
|
||
|
||
//
|
||
// Set the proper node type code and node byte size
|
||
//
|
||
|
||
IrpContext->NodeTypeCode = DSFS_NTC_IRP_CONTEXT;
|
||
IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);
|
||
|
||
//
|
||
// Set the originating Irp field
|
||
//
|
||
|
||
IrpContext->OriginatingIrp = Irp;
|
||
IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
||
|
||
//
|
||
// Major/Minor Function codes
|
||
//
|
||
|
||
IrpContext->MajorFunction = IrpSp->MajorFunction;
|
||
IrpContext->MinorFunction = IrpSp->MinorFunction;
|
||
|
||
//
|
||
// Set the Wait and InFsd flags
|
||
//
|
||
|
||
if (Wait) {
|
||
IrpContext->Flags |= IRP_CONTEXT_FLAG_WAIT;
|
||
}
|
||
|
||
IrpContext->Flags |= IRP_CONTEXT_FLAG_IN_FSD;
|
||
}
|
||
//
|
||
// return and tell the caller
|
||
//
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsCreateIrpContext -> %08lx\n", IrpContext);
|
||
|
||
return IrpContext;
|
||
}
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsDeleteIrpContext, public
|
||
//
|
||
// Synopsis: This routine deallocates and removes the specified
|
||
// IRP_CONTEXT record from the Dsfs in-memory data
|
||
// structures. It should only be called by DfsCompleteRequest.
|
||
//
|
||
// Arguments: [IrpContext] -- Supplies the IRP_CONTEXT to remove
|
||
//
|
||
// Returns: None
|
||
//
|
||
// Notes:
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
VOID
|
||
DfsDeleteIrpContext_Real (
|
||
IN PIRP_CONTEXT IrpContext
|
||
) {
|
||
|
||
DfsDbgTrace(+1, Dbg, "DfsDeleteIrpContext, IrpContext = %08lx\n", IrpContext);
|
||
|
||
ASSERT( IrpContext->NodeTypeCode == DSFS_NTC_IRP_CONTEXT );
|
||
|
||
ExFreeToNPagedLookasideList (&DfsData.IrpContextLookaside, IrpContext);
|
||
|
||
//
|
||
// return and tell the caller
|
||
//
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsDeleteIrpContext -> VOID\n", 0);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsInitializeVcb, public
|
||
//
|
||
// Synopsis: This routine initializes a DFS_VCB.
|
||
//
|
||
// Arguments: [IrpContext] --
|
||
// [Vcb] -- Supplies the address of the Vcb record being
|
||
// initialized.
|
||
// [LogRootPrefix] -- Optional Unicode String pointer that
|
||
// specifies the relative name of the logical
|
||
// root to the highest (org) root.
|
||
// [Credentials] -- The credentials associated with this device
|
||
// [TargetDeviceObject] -- Supplies the address of the target
|
||
// device object to associate with the Vcb record.
|
||
//
|
||
// Returns: None
|
||
//
|
||
// Note: If LogRootPrefix is given, its buffer will be "deallocated"
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
|
||
VOID
|
||
DfsInitializeVcb (
|
||
IN PIRP_CONTEXT IrpContext,
|
||
IN OUT PDFS_VCB Vcb,
|
||
IN PUNICODE_STRING LogRootPrefix,
|
||
IN PDFS_CREDENTIALS Credentials OPTIONAL,
|
||
IN PDEVICE_OBJECT TargetDeviceObject
|
||
) {
|
||
|
||
DfsDbgTrace(+1, Dbg, "DfsInitializeVcb: Entered\n", 0);
|
||
|
||
//
|
||
// Zero out the memory to remove stale data.
|
||
//
|
||
|
||
RtlZeroMemory( Vcb, sizeof( DFS_VCB ));
|
||
|
||
//
|
||
// Set the proper node type code and node byte size.
|
||
//
|
||
|
||
Vcb->NodeTypeCode = DSFS_NTC_VCB;
|
||
Vcb->NodeByteSize = sizeof( DFS_VCB );
|
||
|
||
//
|
||
// Set the prefix string to the input prefix, then `deallocate' the
|
||
// input pointer.
|
||
//
|
||
|
||
Vcb->LogRootPrefix = *LogRootPrefix;
|
||
RtlZeroMemory( LogRootPrefix, sizeof( UNICODE_STRING ));
|
||
|
||
//
|
||
// Save the credentials
|
||
//
|
||
|
||
Vcb->Credentials = Credentials;
|
||
|
||
//
|
||
// Insert this Vcb record on the DfsData.VcbQueue
|
||
//
|
||
|
||
InsertTailList( &DfsData.VcbQueue, &Vcb->VcbLinks );
|
||
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsInitializeVcb: Exit\n", 0);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsCreateFcb, public
|
||
//
|
||
// Synopsis: This routine allocates, initializes, and inserts a new
|
||
// DFS_FCB record into the in-memory data structure.
|
||
//
|
||
// Arguments: [Vcb] -- Supplies the Vcb to associate the new Fcb under
|
||
// [FullName] -- Fully qualified file name for the DFS_FCB
|
||
//
|
||
// Returns: PDFS_FCB - Pointer to the newly created and initialized Fcb.
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
PDFS_FCB
|
||
DfsCreateFcb (
|
||
IN PIRP_CONTEXT IrpContext,
|
||
IN PDFS_VCB Vcb,
|
||
IN PUNICODE_STRING FullName OPTIONAL
|
||
) {
|
||
PDFS_FCB NewFcb;
|
||
ULONG TotalLength;
|
||
|
||
DfsDbgTrace(+1, Dbg, "DfsCreateFcb: Entered\n", 0);
|
||
|
||
//
|
||
// Allocate a new Fcb and zero it out.
|
||
//
|
||
|
||
TotalLength = sizeof(DFS_FCB);
|
||
if (ARGUMENT_PRESENT(FullName))
|
||
TotalLength += FullName->Length * sizeof(WCHAR);
|
||
|
||
NewFcb = (PDFS_FCB) ExAllocatePoolWithTag( NonPagedPool, TotalLength, ' puM' );
|
||
|
||
if (NewFcb != NULL) {
|
||
|
||
RtlZeroMemory( NewFcb, sizeof( DFS_FCB ));
|
||
|
||
//
|
||
// Set the proper node type code and node byte size
|
||
//
|
||
|
||
NewFcb->NodeTypeCode = DSFS_NTC_FCB;
|
||
NewFcb->NodeByteSize = sizeof( DFS_FCB );
|
||
|
||
if (ARGUMENT_PRESENT(FullName)) {
|
||
|
||
NewFcb->FullFileName.Length =
|
||
NewFcb->FullFileName.MaximumLength = FullName->Length;
|
||
|
||
NewFcb->FullFileName.Buffer =
|
||
(PWCHAR) ( (PCHAR)NewFcb + sizeof(DFS_FCB) );
|
||
|
||
RtlMoveMemory( NewFcb->FullFileName.Buffer,
|
||
FullName->Buffer,
|
||
FullName->Length );
|
||
|
||
NewFcb->AlternateFileName.Length = 0;
|
||
|
||
NewFcb->AlternateFileName.MaximumLength = FullName->Length;
|
||
|
||
NewFcb->AlternateFileName.Buffer =
|
||
&NewFcb->FullFileName.Buffer[FullName->Length/sizeof(WCHAR)];
|
||
|
||
}
|
||
|
||
NewFcb->Vcb = Vcb;
|
||
|
||
}
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsCreateFcb -> %8lx\n", NewFcb);
|
||
|
||
return NewFcb;
|
||
}
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsDeleteFcb
|
||
//
|
||
// Synopsis: This routine removes the Fcb record from DSFS's in-memory data
|
||
// structures. It also will remove all associated underlings.
|
||
//
|
||
// Arguments: [Fcb] -- Supplies the Fcb/Dcb to be removed
|
||
//
|
||
// Returns: None
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
VOID
|
||
DfsDeleteFcb_Real (
|
||
IN PIRP_CONTEXT IrpContext,
|
||
IN PDFS_FCB Fcb
|
||
) {
|
||
DfsDbgTrace(+1, Dbg, "DfsDeleteFcb: Fcb = %08lx\n", Fcb);
|
||
|
||
//
|
||
// Zero out the structure and deallocate.
|
||
//
|
||
|
||
ExFreePool( Fcb );
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsDeleteFcb: Exit\n", 0);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsGetLogonId
|
||
//
|
||
// Synopsis: This routine gets the current LogonID.
|
||
// It is assumed that this will be called in the user thread
|
||
// or from a thread that is impersonating the user thread.
|
||
//
|
||
// Arguments: LogonId -- Pointer to LUID where we stuff the LUID
|
||
//
|
||
// Returns: None
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
NTSTATUS
|
||
DfsGetLogonId(
|
||
PLUID LogonId)
|
||
{
|
||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||
|
||
SeCaptureSubjectContext(&SubjectContext);
|
||
|
||
if (SubjectContext.ClientToken != NULL) {
|
||
|
||
//
|
||
// If its impersonating someone that is logged in locally then use
|
||
// the local id.
|
||
//
|
||
|
||
SeQueryAuthenticationIdToken(SubjectContext.ClientToken, LogonId);
|
||
|
||
} else {
|
||
|
||
//
|
||
// Use the processes LogonId
|
||
//
|
||
|
||
SeQueryAuthenticationIdToken(SubjectContext.PrimaryToken, LogonId);
|
||
}
|
||
|
||
SeReleaseSubjectContext(&SubjectContext);
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
|
||
//+-------------------------------------------------------------------
|
||
//
|
||
// Function: DfsInitializeDrt, public
|
||
//
|
||
// Synopsis: This routine initializes a DFS_DEVLESS_ROOT.
|
||
//
|
||
// Arguments: [Drt] -- Supplies the address of the Vcb record being
|
||
// initialized.
|
||
// [Name] -- Unicode String pointer that
|
||
// specifies the relative name of the logical
|
||
// root to the highest (org) root.
|
||
// [Credentials] -- The credentials associated with this device
|
||
//
|
||
// Returns: None
|
||
//
|
||
//--------------------------------------------------------------------
|
||
|
||
|
||
VOID
|
||
DfsInitializeDrt (
|
||
IN OUT PDFS_DEVLESS_ROOT Drt,
|
||
IN PUNICODE_STRING Name,
|
||
IN PDFS_CREDENTIALS Credentials OPTIONAL
|
||
) {
|
||
|
||
DfsDbgTrace(+1, Dbg, "DfsInitializeDevlessRoot: Entered %x\n", Drt);
|
||
|
||
//
|
||
// Zero out the memory to remove stale data.
|
||
//
|
||
|
||
RtlZeroMemory( Drt, sizeof( DFS_DEVLESS_ROOT ));
|
||
|
||
//
|
||
// Set the proper node type code and node byte size.
|
||
//
|
||
|
||
Drt->NodeTypeCode = DSFS_NTC_DRT;
|
||
Drt->NodeByteSize = sizeof( DFS_DEVLESS_ROOT );
|
||
|
||
Drt->DevlessPath = *Name;
|
||
|
||
//
|
||
// Save the credentials
|
||
//
|
||
|
||
Drt->Credentials = Credentials;
|
||
|
||
//
|
||
// Insert this Drt record on the DfsData.DrtQueue
|
||
//
|
||
|
||
InsertTailList( &DfsData.DrtQueue, &Drt->DrtLinks );
|
||
|
||
DfsDbgTrace(-1, Dbg, "DfsInitializeDevlessRoot: Exit\n", 0);
|
||
|
||
return;
|
||
}
|