Leaked source code of windows server 2003
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.
 
 
 
 
 
 

609 lines
15 KiB

/*++
Copyright (c) 1989 - 1999 Microsoft Corporation
Module Name:
openclos.c
Abstract:
This module implements the mini redirector call down routines pertaining to opening/
closing of file/directories.
--*/
#include "precomp.h"
#pragma hdrstop
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_CREATE)
//
// forwards & pragmas
//
NTSTATUS
NulMRxProcessCreate(
IN PNULMRX_FCB_EXTENSION pFcbExtension,
IN PVOID EaBuffer,
IN ULONG EaLength,
OUT PLONGLONG pEndOfFile,
OUT PLONGLONG pAllocationSize
);
NTSTATUS
NulMRxCreateFileSuccessTail (
PRX_CONTEXT RxContext,
PBOOLEAN MustRegainExclusiveResource,
RX_FILE_TYPE StorageType,
ULONG CreateAction,
FILE_BASIC_INFORMATION* pFileBasicInfo,
FILE_STANDARD_INFORMATION* pFileStandardInfo
);
VOID
NulMRxSetSrvOpenFlags (
PRX_CONTEXT RxContext,
RX_FILE_TYPE StorageType,
PMRX_SRV_OPEN SrvOpen
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, NulMRxCreate)
#pragma alloc_text(PAGE, NulMRxShouldTryToCollapseThisOpen)
#pragma alloc_text(PAGE, NulMRxProcessCreate)
#pragma alloc_text(PAGE, NulMRxCreateFileSuccessTail)
#pragma alloc_text(PAGE, NulMRxSetSrvOpenFlags)
#endif
NTSTATUS
NulMRxShouldTryToCollapseThisOpen (
IN PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine determines if the mini knows of a good reason not
to try collapsing on this open. Presently, the only reason would
be if this were a copychunk open.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
SUCCESS --> okay to try collapse
other (MORE_PROCESSING_REQUIRED) --> dont collapse
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
RxCaptureFcb;
PAGED_CODE();
return Status;
}
NTSTATUS
NulMRxCreate(
IN OUT PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine opens a file across the network
Arguments:
RxContext - the RDBSS context
Return Value:
RXSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN fMustRegainExclusiveResource = FALSE;
RX_FILE_TYPE StorageType = FileTypeFile;
ULONG CreateAction = FILE_CREATED;
LARGE_INTEGER liSystemTime;
LONGLONG EndOfFile = 0, AllocationSize = 0;
FILE_BASIC_INFORMATION FileBasicInfo;
FILE_STANDARD_INFORMATION FileStandardInfo;
RxCaptureFcb;
NulMRxGetFcbExtension(capFcb,pFcbExtension);
RX_BLOCK_CONDITION FinalSrvOpenCondition;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SRV_CALL SrvCall = RxContext->Create.pSrvCall;
PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PUNICODE_STRING RemainingName = SrvOpen->pAlreadyPrefixedName;
PVOID EaBuffer = RxContext->Create.EaBuffer;
ULONG EaLength = RxContext->Create.EaLength;
ACCESS_MASK DesiredAccess = RxContext->Create.NtCreateParameters.DesiredAccess;
NulMRxGetNetRootExtension(NetRoot,pNetRootExtension);
RxTraceEnter("NulMRxCreate");
PAGED_CODE();
RxDbgTrace(0, Dbg, (" Attempt to open %wZ Len is %d\n", RemainingName, RemainingName->Length ));
if( NetRoot->Type == NET_ROOT_DISK && NT_SUCCESS(Status) ) {
RxDbgTrace(0, Dbg, ("NulMRxCreate: Type supported \n"));
//
// Squirrel away the scatter list in the FCB extension.
// This is done only for data files.
//
Status = NulMRxProcessCreate(
pFcbExtension,
EaBuffer,
EaLength,
&EndOfFile,
&AllocationSize
);
if( Status != STATUS_SUCCESS ) {
//
// error..
//
RxDbgTrace(0, Dbg, ("Failed to initialize scatter list\n"));
goto Exit;
}
//
// Complete CreateFile contract
//
RxDbgTrace(0,Dbg,("EOF is %d AllocSize is %d\n",(ULONG)EndOfFile,(ULONG)AllocationSize));
FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
KeQuerySystemTime(&liSystemTime);
FileBasicInfo.CreationTime = liSystemTime;
FileBasicInfo.LastAccessTime = liSystemTime;
FileBasicInfo.LastWriteTime = liSystemTime;
FileBasicInfo.ChangeTime = liSystemTime;
FileStandardInfo.AllocationSize.QuadPart = AllocationSize;
FileStandardInfo.EndOfFile.QuadPart = EndOfFile;
FileStandardInfo.NumberOfLinks = 0;
Status = NulMRxCreateFileSuccessTail (
RxContext,
&fMustRegainExclusiveResource,
StorageType,
CreateAction,
&FileBasicInfo,
&FileStandardInfo
);
if( Status != STATUS_SUCCESS ) {
//
// alloc error..
//
RxDbgTrace(0, Dbg, ("Failed to allocate Fobx \n"));
goto Exit;
}
if (!RxIsFcbAcquiredExclusive(capFcb)) {
ASSERT(!RxIsFcbAcquiredShared(capFcb));
RxAcquireExclusiveFcbResourceInMRx( capFcb );
}
} else {
RxDbgTrace(0, Dbg, ("NulMRxCreate: Type not supported or invalid open\n"));
Status = STATUS_NOT_IMPLEMENTED;
}
ASSERT(Status != (STATUS_PENDING));
ASSERT(RxIsFcbAcquiredExclusive( capFcb ));
RxDbgTrace(0, Dbg, ("NetRoot is 0x%x Fcb is 0x%x SrvOpen is 0x%x Fobx is 0x%x\n",
NetRoot,capFcb, SrvOpen,RxContext->pFobx));
RxDbgTrace(0, Dbg, ("NulMRxCreate exit with status=%08lx\n", Status ));
Exit:
RxTraceLeave(Status);
return(Status);
}
NTSTATUS
NulMRxProcessCreate(
IN PNULMRX_FCB_EXTENSION pFcbExtension,
IN PVOID EaBuffer,
IN ULONG EaLength,
OUT PLONGLONG pEndOfFile,
OUT PLONGLONG pAllocationSize
)
/*++
Routine Description:
This routine processes a create calldown.
Arguments:
pFcbExtension - ptr to the FCB extension
EaBuffer - ptr to the EA param buffer
EaLength - len of EaBuffer
pEndOfFile - return end of file value
pAllocationSize - return allocation size (which maybe > EOF)
Notes:
It is possible to create a file with no EAs
Return Value:
None
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
RxDbgTrace(0, Dbg, ("NulMRxInitializeFcbExtension\n"));
*pAllocationSize = *pEndOfFile = 0;
return Status;
}
VOID
NulMRxSetSrvOpenFlags (
PRX_CONTEXT RxContext,
RX_FILE_TYPE StorageType,
PMRX_SRV_OPEN SrvOpen
)
{
PMRX_SRV_CALL SrvCall = (PMRX_SRV_CALL)RxContext->Create.pSrvCall;
//
// set this only if cache manager will be used for mini-rdr handles !
//
SrvOpen->BufferingFlags |= (FCB_STATE_WRITECACHING_ENABLED |
FCB_STATE_FILESIZECACHEING_ENABLED |
FCB_STATE_FILETIMECACHEING_ENABLED |
FCB_STATE_WRITEBUFFERING_ENABLED |
FCB_STATE_LOCK_BUFFERING_ENABLED |
FCB_STATE_READBUFFERING_ENABLED |
FCB_STATE_READCACHING_ENABLED);
}
NTSTATUS
NulMRxCreateFileSuccessTail (
PRX_CONTEXT RxContext,
PBOOLEAN MustRegainExclusiveResource,
RX_FILE_TYPE StorageType,
ULONG CreateAction,
FILE_BASIC_INFORMATION* pFileBasicInfo,
FILE_STANDARD_INFORMATION* pFileStandardInfo
)
/*++
Routine Description:
This routine finishes the initialization of the fcb and srvopen for a
successful open.
Arguments:
Return Value:
RXSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
RxCaptureFcb;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
FCB_INIT_PACKET InitPacket;
RxDbgTrace(0, Dbg, ("MRxExCreateFileSuccessTail\n"));
PAGED_CODE();
ASSERT( NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN );
ASSERT( NodeType(RxContext) == RDBSS_NTC_RX_CONTEXT );
if (*MustRegainExclusiveResource) { //this is required because of oplock breaks
RxAcquireExclusiveFcbResourceInMRx( capFcb );
*MustRegainExclusiveResource = FALSE;
}
// This Fobx should be cleaned up by the wrapper
RxContext->pFobx = RxCreateNetFobx( RxContext, SrvOpen);
if( RxContext->pFobx == NULL ) {
return STATUS_INSUFFICIENT_RESOURCES;
}
ASSERT ( RxIsFcbAcquiredExclusive ( capFcb ) );
RxDbgTrace(0, Dbg, ("Storagetype %08lx/Action %08lx\n", StorageType, CreateAction ));
RxContext->Create.ReturnedCreateInformation = CreateAction;
RxFormInitPacket(
InitPacket,
&pFileBasicInfo->FileAttributes,
&pFileStandardInfo->NumberOfLinks,
&pFileBasicInfo->CreationTime,
&pFileBasicInfo->LastAccessTime,
&pFileBasicInfo->LastWriteTime,
&pFileBasicInfo->ChangeTime,
&pFileStandardInfo->AllocationSize,
&pFileStandardInfo->EndOfFile,
&pFileStandardInfo->EndOfFile);
if (capFcb->OpenCount == 0) {
RxFinishFcbInitialization( capFcb,
RDBSS_STORAGE_NTC(StorageType),
&InitPacket
);
} else {
ASSERT( StorageType == 0 || NodeType(capFcb) == RDBSS_STORAGE_NTC(StorageType));
}
NulMRxSetSrvOpenFlags(RxContext,StorageType,SrvOpen);
RxContext->pFobx->OffsetOfNextEaToReturn = 1;
//transition happens later
return Status;
}
NTSTATUS
NulMRxCollapseOpen(
IN OUT PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine collapses a open locally
Arguments:
RxContext - the RDBSS context
Return Value:
RXSTATUS - The return status for the operation
--*/
{
NTSTATUS Status;
RxCaptureFcb;
RxCaptureRequestPacket;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SRV_CALL SrvCall = RxContext->Create.pSrvCall;
PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
RxTraceEnter("NulMRxCollapseOpen");
RxContext->pFobx = (PMRX_FOBX)RxCreateNetFobx( RxContext, SrvOpen);
if (RxContext->pFobx != NULL) {
ASSERT ( RxIsFcbAcquiredExclusive ( capFcb ) );
RxContext->pFobx->OffsetOfNextEaToReturn = 1;
capReqPacket->IoStatus.Information = FILE_OPENED;
Status = STATUS_SUCCESS;
} else {
Status = (STATUS_INSUFFICIENT_RESOURCES);
DbgBreakPoint();
}
RxTraceLeave(Status);
return Status;
}
NTSTATUS
NulMRxComputeNewBufferingState(
IN OUT PMRX_SRV_OPEN pMRxSrvOpen,
IN PVOID pMRxContext,
OUT PULONG pNewBufferingState)
/*++
Routine Description:
This routine maps specific oplock levels into the appropriate RDBSS
buffering state flags
Arguments:
pMRxSrvOpen - the MRX SRV_OPEN extension
pMRxContext - the context passed to RDBSS at Oplock indication time
pNewBufferingState - the place holder for the new buffering state
Return Value:
Notes:
--*/
{
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
DbgPrint("NulMRxComputeNewBufferingState \n");
return(Status);
}
NTSTATUS
NulMRxDeallocateForFcb (
IN OUT PMRX_FCB pFcb
)
{
NTSTATUS Status = STATUS_SUCCESS;
NulMRxGetFcbExtension(pFcb,pFcbExtension);
PMRX_NET_ROOT pNetRoot = pFcb->pNetRoot;
NulMRxGetNetRootExtension(pNetRoot,pNetRootExtension);
RxTraceEnter("NulMRxDeallocateForFcb\n");
RxTraceLeave(Status);
return(Status);
}
NTSTATUS
NulMRxTruncate(
IN PRX_CONTEXT pRxContext)
/*++
Routine Description:
This routine truncates the contents of a file system object
Arguments:
pRxContext - the RDBSS context
Return Value:
RXSTATUS - The return status for the operation
--*/
{
ASSERT(!"Found a truncate");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NulMRxCleanupFobx(
IN PRX_CONTEXT RxContext)
/*++
Routine Description:
This routine cleansup a file system object...normally a noop. unless it's a pipe in which case
we do the close at cleanup time and mark the file as being not open.
Arguments:
pRxContext - the RDBSS context
Return Value:
RXSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PUNICODE_STRING RemainingName;
RxCaptureFcb; RxCaptureFobx;
NODE_TYPE_CODE TypeOfOpen = NodeType(capFcb);
PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
BOOLEAN SearchHandleOpen = FALSE;
PAGED_CODE();
ASSERT( NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN );
ASSERT ( NodeTypeIsFcb(capFcb) );
RxDbgTrace( 0, Dbg, ("NulMRxCleanupFobx\n"));
if (FlagOn(capFcb->FcbState,FCB_STATE_ORPHANED)) {
RxDbgTrace( 0, Dbg, ("File orphaned\n"));
return (STATUS_SUCCESS);
}
if ((capFcb->pNetRoot->Type != NET_ROOT_PIPE) && !SearchHandleOpen) {
RxDbgTrace( 0, Dbg, ("File not for closing at cleanup\n"));
return (STATUS_SUCCESS);
}
RxDbgTrace( 0, Dbg, ("NulMRxCleanup exit with status=%08lx\n", Status ));
return(Status);
}
NTSTATUS
NulMRxForcedClose(
IN PMRX_SRV_OPEN pSrvOpen)
/*++
Routine Description:
This routine closes a file system object
Arguments:
pSrvOpen - the instance to be closed
Return Value:
RXSTATUS - The return status for the operation
Notes:
--*/
{
RxDbgTrace( 0, Dbg, ("NulMRxForcedClose\n"));
return STATUS_SUCCESS;
}
//
// The local debug trace level
//
#undef Dbg
#define Dbg (DEBUG_TRACE_CLOSE)
NTSTATUS
NulMRxCloseSrvOpen(
IN PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine closes a file across the network
Arguments:
RxContext - the RDBSS context
Return Value:
RXSTATUS - The return status for the operation
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
RxCaptureFcb;
RxCaptureFobx;
PMRX_SRV_OPEN pSrvOpen = capFobx->pSrvOpen;
PUNICODE_STRING RemainingName = pSrvOpen->pAlreadyPrefixedName;
PMRX_SRV_OPEN SrvOpen;
NODE_TYPE_CODE TypeOfOpen = NodeType(capFcb);
PMRX_NET_ROOT pNetRoot = capFcb->pNetRoot;
NulMRxGetNetRootExtension(pNetRoot,pNetRootExtension);
RxDbgTrace( 0, Dbg, ("NulMRxCloseSrvOpen \n"));
SrvOpen = capFobx->pSrvOpen;
return(Status);
}
NTSTATUS
NulMRxDeallocateForFobx (
IN OUT PMRX_FOBX pFobx
)
{
RxDbgTrace( 0, Dbg, ("NulMRxDeallocateForFobx\n"));
return(STATUS_SUCCESS);
}