|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
webdav.h
Abstract:
This module defines the data structures and functions related to the WebDav protocol.
Author:
Rohan Kumar [rohank] 17-Mar-1999
Revision History:
--*/
#ifndef _WEBDAV_H
#define _WEBDAV_H
#ifdef RX_PRIVATE_BUILD
#undef IoGetTopLevelIrp
#undef IoSetTopLevelIrp
#endif
//
// The miniredir dipatch vector used by RDBSS.
//
extern struct _MINIRDR_DISPATCH MRxDAVDispatch;
//
// A serialization mutex used for various things.
//
extern FAST_MUTEX MRxDAVSerializationMutex;
//
// A pointer to the process that the RDBSS posts to. This is a non disappearing
// process!
//
extern PEPROCESS MRxDAVSystemProcess;
//
// The DavWinInetCachePath which is used in satisfying volume related queries.
//
extern WCHAR DavWinInetCachePath[MAX_PATH];
//
// The ProcessId of the svchost.exe process that loads the webclnt.dll.
//
extern ULONG DavSvcHostProcessId;
//
// The exchange device name will be stored in this KEY_VALUE_PARTIAL_INFORMATION
// structure.
//
extern PBYTE DavExchangeDeviceName;
//
// Name cache stuff. These values are read from the registry during init time.
//
extern ULONG FileInformationCacheLifeTimeInSec; extern ULONG FileNotFoundCacheLifeTimeInSec; extern ULONG NameCacheMaxEntries;
//
// The timeout values for various operations used by the MiniRedir. If an
// operation is not completed within the timeout value specified for it, is
// cancelled. The user can set the value to 0xffffffff to disable the
// timeout/cancel logic. In other words, if the timeout value is 0xffffffff,
// the requests will never timeout.
//
extern ULONG CreateRequestTimeoutValueInSec; extern ULONG CreateVNetRootRequestTimeoutValueInSec; extern ULONG QueryDirectoryRequestTimeoutValueInSec; extern ULONG CloseRequestTimeoutValueInSec; extern ULONG CreateSrvCallRequestTimeoutValueInSec; extern ULONG FinalizeSrvCallRequestTimeoutValueInSec; extern ULONG FinalizeFobxRequestTimeoutValueInSec; extern ULONG FinalizeVNetRootRequestTimeoutValueInSec; extern ULONG ReNameRequestTimeoutValueInSec; extern ULONG SetFileInfoRequestTimeoutValueInSec; extern ULONG QueryFileInfoRequestTimeoutValueInSec; extern ULONG QueryVolumeInfoRequestTimeoutValueInSec; extern ULONG LockRefreshRequestTimeoutValueInSec;
//
// The timer thread wakes up every "TimerThreadSleepTimeInSec" and cancels all
// the requests which haven't completed in their specified timeout value. This
// value is set to the min of the timeout values of all the requests mentioned
// above.
//
extern ULONG TimerThreadSleepTimeInSec;
//
// The timer object used by the timer thread that cancels the requests which
// have not completed in a specified time.
//
extern KTIMER DavTimerObject;
//
// This is used to indicate the timer thread to shutdown. When the system is
// being shutdown this is set to TRUE. MRxDAVTimerThreadLock is the resource
// used to gain access to this variable.
//
extern BOOL TimerThreadShutDown; extern ERESOURCE MRxDAVTimerThreadLock;
//
// The handle of the timer thread that is created using PsCreateSystemThread
// is stored this global.
//
extern HANDLE TimerThreadHandle;
//
// This event is signalled by the timer thread right before its going to
// terminate itself.
//
extern KEVENT TimerThreadEvent;
//
// If QueueLockRefreshWorkItem is TRUE, the TimerThread (which cancels all the
// AsyncEngineContexts that haven't completed in a specified time) queues a
// WorkItem to refresh the locks. After the WorkItem has been queued the value
// of QueueLockRefreshWorkItem is set to FALSE. Once the worker thread is
// done refreshing all the locks, it resets this value to TRUE. We have a
// corresponding lock QueueLockRefreshWorkItemLock to synchronize access to
// QueueLockRefreshWorkItem.
//
extern BOOL QueueLockRefreshWorkItem; extern ERESOURCE QueueLockRefreshWorkItemLock;
//
// The WorkQueueItem used in the MRxDAVContextTimerThread function to refresh
// the LOCKs taken by this client.
//
extern RX_WORK_QUEUE_ITEM LockRefreshWorkQueueItem;
#define DAV_MJ_READ 0
#define DAV_MJ_WRITE 1
//
// Pool tags used by the reflector library. All the DAV MiniRedir pool tags
// have "DV" as the first two characters.
//
#define DAV_SRVCALL_POOLTAG ('cSVD')
#define DAV_NETROOT_POOLTAG ('tNVD')
#define DAV_FILEINFO_POOLTAG ('iFVD')
#define DAV_FILENAME_POOLTAG ('nFVD')
#define DAV_EXCHANGE_POOLTAG ('xEVD')
#define DAV_READWRITE_POOLTAG ('wRVD')
#define DAV_QUERYDIR_POOLTAG ('dQVD')
#define DAV_SRVOPEN_POOLTAG ('oSVD')
#define DAV_LOCKTOKENENTRY_POOLTAG ('tLVD')
#define DAV_LOCKCONFLICTENTRY_POOLTAG ('cLVD')
//
// Use the DavDbgTrace macro for logging Mini-Redir stuff in the kernel
// debugger.
//
#if DBG
extern ULONG MRxDavDebugVector; #define DAV_TRACE_ERROR 0x00000001
#define DAV_TRACE_DEBUG 0x00000002
#define DAV_TRACE_CONTEXT 0x00000004
#define DAV_TRACE_DETAIL 0x00000008
#define DAV_TRACE_ENTRYEXIT 0x00000010
#define DAV_TRACE_QUERYDIR 0x00000020
#define DAV_TRACE_OPENCLOSE 0x00000040
#define DAV_TRACE_READ 0x00000080
#define DAV_TRACE_WRITE 0x00000100
#define DAV_TRACE_SRVCALL 0x00000200
#define DAV_TRACE_FCBFOBX 0x00000400
#define DAV_TRACE_DAVNETROOT 0x00000800
#define DAV_TRACE_INFOCACHE 0x00001000
#define DAV_TRACE_ALL 0xffffffff
#define DavDbgTrace(_x_, _y_) { \
if (_x_ & MRxDavDebugVector) { \ DbgPrint _y_; \ } \ } #else
#define DavDbgTrace(_x_, _y_)
#endif
//
// The initialization states of the miniredir.
//
typedef enum _WEBDAV_INIT_STATES { MRxDAVINIT_START, MRxDAVINIT_MINIRDR_REGISTERED } WEBDAV_INIT_STATES;
//
// These are used by the entry point routines to specify what entrypoint was
// called. This facilitates common continuation routines.
//
typedef enum _WEBDAV_MINIRDR_ENTRYPOINTS { DAV_MINIRDR_ENTRY_FROM_CREATE = 0, DAV_MINIRDR_ENTRY_FROM_CLEANUPFOBX, DAV_MINIRDR_ENTRY_FROM_CREATESRVCALL, DAV_MINIRDR_ENTRY_FROM_CREATEVNETROOT, DAV_MINIRDR_ENTRY_FROM_FINALIZESRVCALL, DAV_MINIRDR_ENTRY_FROM_FINALIZEVNETROOT, DAV_MINIRDR_ENTRY_FROM_CLOSESRVOPEN, DAV_MINIRDR_ENTRY_FROM_RENAME, DAV_MINIRDR_ENTRY_FROM_READ, DAV_MINIRDR_ENTRY_FROM_WRITE, DAV_MINIRDR_ENTRY_FROM_QUERYDIR, DAV_MINIRDR_ENTRY_FROM_SETFILEINFORMATION, DAV_MINIRDR_ENTRY_FROM_QUERYFILEINFORMATION, DAV_MINIRDR_ENTRY_FROM_QUERYVOLUMEINFORMATION, DAV_MINIRDR_ENTRY_FROM_REFRESHTHELOCK, DAV_MINIRDR_ENTRY_FROM_MAXIMUM } WEBDAV_MINIRDR_ENTRYPOINTS;
//
// The states of the I/O operation(s).
//
typedef enum _WEBDAV_INNERIO_STATE { MRxDAVInnerIoStates_Initial = 0, MRxDAVInnerIoStates_ReadyToSend, MRxDAVInnerIoStates_OperationOutstanding } WEBDAV_INNERIO_STATE;
//
// The WebDav context structure that encapsulates the AsyncEngineCtx structure
// and has the miniredir specific fields.
//
typedef struct _WEBDAV_CONTEXT {
//
// The AsyncEngineCtx Structure used by the Reflector library.
//
union { UMRX_ASYNCENGINE_CONTEXT; UMRX_ASYNCENGINE_CONTEXT AsyncEngineContext; };
//
// This is used by the entry point routines to specify what entrypoint was
// called. This facilitates common continuation routines.
//
WEBDAV_MINIRDR_ENTRYPOINTS EntryPoint;
//
// These describe the inner state of the I/O operation. These states are
// described in the MRxDAV_INNERIO_STATE data structure.
//
UCHAR OpSpecificState;
//
// Pointer to the information strucutre for the Create request.
//
PDAV_USERMODE_CREATE_RETURNED_FILEINFO CreateReturnedFileInfo;
//
// This is used in the Continuation functions for the read, write and
// querydir calls. It keeps track of the number of times the Continuation
// routine has been called.
//
ULONG ContinueEntryCount;
} WEBDAV_CONTEXT, *PWEBDAV_CONTEXT;
//
// While creating the AsyncEngineContext, the extra space needed for the
// miniredir specific fields is also allocated. Thus, one doesn't need to
// allocate twice.
//
#define SIZEOF_DAV_SPECIFIC_CONTEXT \
sizeof(WEBDAV_CONTEXT) - sizeof(UMRX_ASYNCENGINE_CONTEXT)
//
// The WebDav device object structure that encapsulates the UMRX_DEVICE_OBJECT
// structure and has the miniredir specific fields.
//
typedef struct _WEBDAV_DEVICE_OBJECT {
//
// The UMRX_DEVICE_OBJECT structure.
//
union { UMRX_DEVICE_OBJECT; UMRX_DEVICE_OBJECT UMRefDeviceObject; };
//
// TRUE => miniredir has been started.
//
BOOLEAN IsStarted;
//
// The FCB of the device object.
//
PVOID CachedRxDeviceFcb;
//
// The process registering this device object.
//
PEPROCESS RegisteringProcess;
} WEBDAV_DEVICE_OBJECT, *PWEBDAV_DEVICE_OBJECT;
//
// The Dav device object.
//
extern PWEBDAV_DEVICE_OBJECT MRxDAVDeviceObject;
//
// The extra number of bytes needed for the device object. This info is used
// when the device object gets created.
//
#define WEBDAV_DEVICE_OBJECT_EXTENSION_SIZE \
(sizeof(WEBDAV_DEVICE_OBJECT) - sizeof(RDBSS_DEVICE_OBJECT))
//
// For every LOCK that is taken for a file, the following entry is created and
// added to the global LockTokenEntryList.
//
typedef struct _WEBDAV_LOCK_TOKEN_ENTRY {
LIST_ENTRY listEntry;
//
// The LockToken that was returned by the server on a successful LOCK
// request.
//
PWCHAR OpaqueLockToken;
//
// The server on which the file is shared.
//
PWCHAR ServerName;
//
// The path of the file on the server.
//
PWCHAR PathName;
//
// The ServerHashTable ServerId of this server.
//
ULONG ServerID;
//
// The LogonId of this user.
//
LUID LogonID;
//
// If this is set to FALSE, this LockEntry is not refreshed.
//
BOOL ShouldThisEntryBeRefreshed;
//
// The SecurityClientContext of the client in whose context the LOCK was
// taken. This is needed to impersonate the client when refreshing the
// LOCK.
//
PSECURITY_CLIENT_CONTEXT SecurityClientContext;
//
// The timeout value of the LOCK taken on the server. If the client wants
// to hold the LOCK beyond this timeout then it needs to refresh the LOCK
// before the timeout expires.
//
ULONG LockTimeOutValueInSec;
//
// The system tick count when this LOCK entry was created. This value is
// used in sending out LOCK refresh requests.
//
LARGE_INTEGER CreationTimeInTickCount;
} WEBDAV_LOCK_TOKEN_ENTRY, *PWEBDAV_LOCK_TOKEN_ENTRY;
//
// The global list of all the active LOCK tokens (one for every LOCK taken) and
// the resource that is used to synchronize access to it.
//
extern LIST_ENTRY LockTokenEntryList; extern ERESOURCE LockTokenEntryListLock;
#define WEBDAV_LOCKCONFLICTENTRY_LIFETIMEINSEC 10
//
// For every LOCK request that fails, we create an entry below and add it to
// the global LockConflictEntryList.
//
typedef struct _WEBDAV_LOCK_CONFLICT_ENTRY {
LIST_ENTRY listEntry;
//
// The complete path name of the file that has already been locked on the
// server.
//
PWCHAR CompletePathName;
//
// The owner of the LOCK on the file as returned by the server.
//
PWCHAR LockOwner;
//
// The system tick count when this entry was created. This entry is kept
// alive for WEBDAV_LOCKCONFLICTENTRY_LIFETIMEINSEC seconds.
//
LARGE_INTEGER CreationTimeInTickCount;
} WEBDAV_LOCK_CONFLICT_ENTRY, *PWEBDAV_LOCK_CONFLICT_ENTRY;
//
// The global list of all the LOCK conflict entries and the resource that is
// used to synchronize access to it.
//
extern LIST_ENTRY LockConflictEntryList; extern ERESOURCE LockConflictEntryListLock;
//
// The WEBDAV specific FOBX structure.
//
typedef struct _WEBDAV_FOBX {
//
// The pointer to the DavFileAttribute list for this directory. This list
// is created on the first call to Enumerate files in the directory.
//
PDAV_FILE_ATTRIBUTES DavFileAttributes;
//
// Number of DavFileAttribute entries.
//
ULONG NumOfFileEntries;
//
// The index of the next file to be returned to the user. The file index
// starts from zero, hence file index = 0 => the first file entry etc.
//
ULONG CurrentFileIndex;
//
// Pointer to the next entry.
//
PLIST_ENTRY listEntry;
} WEBDAV_FOBX, *PWEBDAV_FOBX;
//
// A pointer to an instance of WEBDAV_SRV_OPEN is stored in the context field
// of MRX_SRV_OPEN strucutre.
//
#define MRxDAVGetFobxExtension(pFobx) \
(((pFobx) == NULL) ? NULL : (PWEBDAV_FOBX)((pFobx)->Context))
//
// The WEBDAV specific SRV_OPEN structure.
//
typedef struct _WEBDAV_SRV_OPEN {
//
// The file handle associated with this SrvOpen.
//
HANDLE UnderlyingHandle;
//
// This also is the handle got from the usermode. Its used for debugging
// purposes.
//
PVOID UserModeKey;
//
// Pointer to the file object associated with the handle. This is set
// after the handle is successfully created in the usermode.
//
PFILE_OBJECT UnderlyingFileObject;
//
// Pointer to the device object represented by the file object mentioned
// above.
//
PDEVICE_OBJECT UnderlyingDeviceObject;
//
// This indicates whether we need to call IoRaiseInformationalHardError
// when the close fails. We need to do this if the PUT or DELETE failed and
// the operation which the user expects has succeeded actually failed.
//
BOOL RaiseHardErrorIfCloseFails;
//
// Created In Kernel.
//
BOOL createdInKernel;
//
// The OpaqueLockToken returned by the server if the file was LOCKed on
// Create. This token has to be sent with every request that modifies the
// data or the properties of this file.
//
PWCHAR OpaqueLockToken;
//
// The LockTokenEntry created for the OpaqueLockToken above.
//
PWEBDAV_LOCK_TOKEN_ENTRY LockTokenEntry;
} WEBDAV_SRV_OPEN, *PWEBDAV_SRV_OPEN;
//
// A pointer to an instance of WEBDAV_SRV_OPEN is stored in the context field
// of MRX_SRV_OPEN strucutre.
//
#define MRxDAVGetSrvOpenExtension(pSrvOpen) \
(((pSrvOpen) == NULL) ? NULL : (PWEBDAV_SRV_OPEN)((pSrvOpen)->Context)) //
// The WEBDAV specific FCB structure.
//
typedef struct _WEBDAV_FCB {
//
// Is this FCB for a directory ?
//
BOOL isDirectory;
//
// Does the File exist in the WinInet cache ??
//
BOOL isFileCached; //
// Should this file be deleted on Close ?
//
BOOL DeleteOnClose;
//
// Was this file written to ?
//
ULONG FileWasModified;
//
// Did we reset the FileWasModified in the DavFcb to FALSE? If we did and
// the PUT failed, we need to reset the FileWasModified field in the FCB to
// TRUE.
//
BOOL FileModifiedBitReset;
//
// If we happen to LOCK the file on the server on Create we set this to
// TRUE. On CloseSrvOpen we check if this value is TRUE. If it is and the
// file has been modified, we only go to the usermode to do the PUT, DELETE,
// PROPPATCH etc, if the SrvOpen contains the OpaqueLockToken. If it does
// not then any request that modifies the file is going to fail with a
// 423.
//
BOOL FileIsLockedOnTheServer;
//
// On Close, if the file has been modified, we PROPPATCH the time values
// as well. We take the current time as the value of the "Last Modified Time"
// (LMT). If the SetFileInformation of the LMT happens after the file has
// been modifed, then we should use what ever LMT is already in the FCB as
// the LMT. For example,
// Create, Write, Close - Use the CurrentTime in close as the LMT.
// Create, Write, SetFileInfo(LMT), Close - Use the LMT in the FCB.
//
BOOL DoNotTakeTheCurrentTimeAsLMT;
//
// This resource is used to synchronize the "Read-Modify-Write" routine
// in the Write path of the DAV Redir. This is because when we get non-cached
// writes to the MiniRedir which do not extend the VaildDataLength, RDBSS,
// acquires the FCB resource shared. This means that multiple threads could
// be writing data to the local file (in the DAV Redir case) in which case
// they can overwrite each others changes since we do Read-Modify-Write.
// Hence we need to protect this code using a resource which we acqiure
// in an exclusive fashion when we do these writes. We allocate memory for
// this resource and initialize it the first time we need to acquire the
// lock. If allocated and initialized, it will be uninitialized and
// deallocated when the FCB is being deallocated.
//
PERESOURCE DavReadModifyWriteLock;
//
// We store the file name information on create. This is used if the delayed
// write failed to pop up the dialogue box and write an eventlog entry.
//
UNICODE_STRING FileNameInfo; BOOL FileNameInfoAllocated;
//
// Changes in directory entry.
//
BOOLEAN fCreationTimeChanged;
BOOLEAN fLastAccessTimeChanged;
BOOLEAN fLastModifiedTimeChanged;
BOOLEAN fFileAttributesChanged;
//
// Was this file renamed ?
//
BOOL FileWasRenamed;
BOOL LocalFileIsEncrypted;
SECURITY_CLIENT_CONTEXT SecurityClientContext;
//
// If the file gets renamed, the new name is copied into this buffer.
//
WCHAR NewFileName[MAX_PATH];
//
// Length of the new file name.
//
ULONG NewFileNameLength;
//
// The file name of the local file that represents the file on the DAV
// server which has been created.
//
WCHAR FileName[MAX_PATH]; WCHAR Url[MAX_PATH * 2];
} WEBDAV_FCB, *PWEBDAV_FCB;
//
// A pointer to an instance of WEBDAV_FCB is stored in the context field
// of MRX_FCB strucutre.
//
#define MRxDAVGetFcbExtension(pFcb) \
(((pFcb) == NULL) ? NULL : (PWEBDAV_FCB)((pFcb)->Context)) //
// The WEBDAV specific V_NET_ROOT structure.
//
typedef struct _WEBDAV_V_NET_ROOT {
//
// The client's security context. This is set during the create call.
//
SECURITY_CLIENT_CONTEXT SecurityClientContext;
//
// Is set to true after the above context is set. This is used to avoid
// initialization of the SecurityContext.
//
BOOLEAN SCAlreadyInitialized;
//
// Has the LogonID of this V_NET_ROOT been set ?
//
BOOL LogonIDSet;
//
// The LogonID for this session.
//
LUID LogonID;
//
// Is this an Office Web Server share?
//
BOOL isOfficeShare; //
// Is this a TAHOE share?
//
BOOL isTahoeShare; //
// Is PROPATCH method allowed?
//
BOOL fAllowsProppatch;
//
// Was this VNetRoot "NOT" created successfully in the usermode? We keep this
// info because when a finalize VNetRoot request comes, we need to know
// whether need to go upto the usermode to finalize the PerUserEntry. If the
// create failed then this BOOL is set to TRUE. If this is TRUE, then we
// don't go to the usermode to finalize the PerUserEntry.
//
BOOL createVNetRootUnSuccessful;
// does he report available space?
BOOL fReportsAvailableSpace;
} WEBDAV_V_NET_ROOT, *PWEBDAV_V_NET_ROOT;
//
// The WEBDAV specific V_NET_ROOT structure.
//
typedef struct _WEBDAV_NET_ROOT { ULONG RefCount; PMRX_NET_ROOT pRdbssNetRoot; // The Rdbss NetRoot it belongs to
NAME_CACHE_CONTROL NameCacheCtlGFABasic; // The basic file information name cache control.
NAME_CACHE_CONTROL NameCacheCtlGFAStandard; // The standard file information name cache control.
NAME_CACHE_CONTROL NameCacheCtlFNF; // The File not found name cache control.
} WEBDAV_NET_ROOT, *PWEBDAV_NET_ROOT;
//
// A pointer to an instance of WEBDAV_V_NET_ROOT is stored in the context field
// of MRX_V_NET_ROOT strucutre.
//
#define MRxDAVGetVNetRootExtension(pVNetRoot) \
(((pVNetRoot) == NULL) ? NULL : (PWEBDAV_V_NET_ROOT)((pVNetRoot)->Context))
//
// The WEBDAV specific V_NET_ROOT structure.
//
typedef struct _WEBDAV_SRV_CALL {
//
// The Unique ServerID.
//
ULONG ServerID;
//
// Is set to true after the above context is set. Used to check whether we
// need to delete the SecurityClientContext when we are completing the
// request.
//
BOOLEAN SCAlreadyInitialized;
} WEBDAV_SRV_CALL, *PWEBDAV_SRV_CALL;
//
// A pointer to an instance of WEBDAV_SRV_CALL is stored in the context field
// of MRX_SRV_CALL strucutre.
//
#define MRxDAVGetSrvCallExtension(pSrvCall) \
(((pSrvCall) == NULL) ? NULL : (PWEBDAV_SRV_CALL)((pSrvCall)->Context))
//
// Get the Security client context associated with this request.
//
#define MRxDAVGetSecurityClientContext() { \
if (RxContext != NULL && RxContext->pRelevantSrvOpen != NULL) { \ if (RxContext->pRelevantSrvOpen->pVNetRoot != NULL) { \ if (RxContext->pRelevantSrvOpen->pVNetRoot->Context != NULL) { \ DavVNetRoot = (PWEBDAV_V_NET_ROOT) \ RxContext->pRelevantSrvOpen->pVNetRoot->Context; \ SecurityClientContext = &(DavVNetRoot->SecurityClientContext); \ } \ } \ } \ }
//
// We turn away async operations that are not wait by posting. If we can wait
// then we turn off the sync flag so that things will just act synchronous.
//
#define TURN_BACK_ASYNCHRONOUS_OPERATIONS() { \
if (FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION)) { \ if (FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT)) { \ ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION) \ } else { \ RxContext->PostRequest = TRUE; \ return STATUS_PENDING; \ } \ } \ }
//
// Global locking variables and macros.
//
extern RX_SPIN_LOCK MRxDAVGlobalSpinLock; extern KIRQL MRxDAVGlobalSpinLockSavedIrql; extern BOOLEAN MRxDAVGlobalSpinLockAcquired;
#define MRxDAVAcquireGlobalSpinLock() \
KeAcquireSpinLock(&MRxDAVGlobalSpinLock,&MRxDAVGlobalSpinLockSavedIrql); \ MRxDAVGlobalSpinLockAcquired = TRUE
#define MRxDAVReleaseGlobalSpinLock() \
MRxDAVGlobalSpinLockAcquired = FALSE; \ KeReleaseSpinLock(&MRxDAVGlobalSpinLock,MRxDAVGlobalSpinLockSavedIrql)
#define MRxDAVGlobalSpinLockAcquired() \
(MRxDAVGlobalSpinLockAcquired == TRUE)
//
// The IrpCompletionContext structure that is used in the read/write operations.
// All we need is an event on which we will wait till the underlying file system
// completes the request. This event gets signalled in the Completion routine
// that we specify.
//
typedef struct _WEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT {
//
// The event which is signalled in the Completion routine that is passed
// to IoCallDriver in the read and write requests.
//
KEVENT DavReadWriteEvent;
} WEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT, *PWEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT;
//
// The prototypes of functions defined for various I/O requests by the DAV
// miniredir are mentioned below.
//
//
// Create/Open/Cleanup/Close Request function prototypes.
//
NTSTATUS MRxDAVCreate( IN PRX_CONTEXT RxContext );
NTSTATUS MRxDAVCleanupFobx ( IN OUT PRX_CONTEXT RxContext );
NTSTATUS MRxDAVCloseSrvOpen ( IN OUT PRX_CONTEXT RxContext );
NTSTATUS MRxDAVCollapseOpen ( IN OUT PRX_CONTEXT RxContext );
NTSTATUS MRxDAVComputeNewBufferingState( IN OUT PMRX_SRV_OPEN pSrvOpen, IN PVOID pMRxContext, OUT ULONG *pNewBufferingState );
NTSTATUS MRxDAVForcedClose ( IN OUT PMRX_SRV_OPEN SrvOpen );
NTSTATUS MRxDAVShouldTryToCollapseThisOpen ( IN PRX_CONTEXT RxContext );
NTSTATUS MRxDAVTruncate ( IN OUT PRX_CONTEXT RxContext );
VOID MRxDAVSetLoud( IN PBYTE Msg, IN PRX_CONTEXT RxContext, IN PUNICODE_STRING s );
NTSTATUS MRxDAVFlush ( IN OUT PRX_CONTEXT RxContext );
//
// Read prototypes.
//
NTSTATUS MRxDAVRead ( IN OUT PRX_CONTEXT RxContext );
//
// Write prototypes.
//
NTSTATUS MRxDAVWrite( IN PRX_CONTEXT RxContext );
ULONG MRxDAVExtendForCache( IN OUT PRX_CONTEXT RxContext, IN OUT PLARGE_INTEGER NewFileSize, OUT PLARGE_INTEGER NewAllocationSize );
ULONG MRxDAVExtendForNonCache( IN OUT PRX_CONTEXT RxContext, IN OUT PLARGE_INTEGER NewFileSize, OUT PLARGE_INTEGER NewAllocationSize );
//
// SrvCall function prototypes.
//
NTSTATUS MRxDAVCreateSrvCall( PMRX_SRV_CALL pSrvCall, PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext );
NTSTATUS MRxDAVFinalizeSrvCall( PMRX_SRV_CALL pSrvCall, BOOLEAN Force );
NTSTATUS MRxDAVSrvCallWinnerNotify( IN PMRX_SRV_CALL pSrvCall, IN BOOLEAN ThisMinirdrIsTheWinner, IN OUT PVOID pSrvCallContext );
//
// NetRoot/VNetRoot function prototypes.
//
NTSTATUS MRxDAVUpdateNetRootState( IN OUT PMRX_NET_ROOT pNetRoot );
NTSTATUS MRxDAVCreateVNetRoot( IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext );
NTSTATUS MRxDAVFinalizeVNetRoot( IN PMRX_V_NET_ROOT pVNetRoot, IN PBOOLEAN ForceDisconnect );
NTSTATUS MRxDAVFinalizeNetRoot( IN PMRX_NET_ROOT pNetRoot, IN PBOOLEAN ForceDisconnect );
VOID MRxDAVExtractNetRootName( IN PUNICODE_STRING FilePathName, IN PMRX_SRV_CALL SrvCall, OUT PUNICODE_STRING NetRootName, OUT PUNICODE_STRING RestOfName OPTIONAL );
//
// Query Directory prototypes.
//
NTSTATUS MRxDAVQueryDirectory( IN PRX_CONTEXT RxContext );
//
// Query volume.
//
NTSTATUS MRxDAVQueryVolumeInformation( IN PRX_CONTEXT RxContext );
//
// File Information.
//
NTSTATUS MRxDAVQueryFileInformation( IN PRX_CONTEXT RxContext );
NTSTATUS MRxDAVSetFileInformation( IN PRX_CONTEXT RxContext );
//
// DevFcb prototypes.
//
NTSTATUS MRxDAVDevFcbXXXControlFile ( IN OUT PRX_CONTEXT RxContext );
NTSTATUS MRxDAVStart ( IN OUT struct _RX_CONTEXT * RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject );
NTSTATUS MRxDAVStop ( IN OUT struct _RX_CONTEXT * RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject );
BOOLEAN MRxDAVFastIoDeviceControl ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject );
BOOLEAN MRxDAVFastIoRead( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
BOOLEAN MRxDAVFastIoWrite( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
//
// Other Misc prototypes.
//
NTSTATUS MRxDAVSyncXxxInformation( IN OUT PRX_CONTEXT RxContext, IN UCHAR MajorFunction, IN PFILE_OBJECT FileObject, IN ULONG InformationClass, IN ULONG Length, OUT PVOID Information, OUT PULONG_PTR ReturnedLength OPTIONAL );
NTSTATUS MRxDAVDeallocateForFcb ( IN OUT PMRX_FCB pFcb );
NTSTATUS MRxDAVDeallocateForFobx ( IN OUT PMRX_FOBX pFobx );
//
// The prototype of the routine that formats the DAV specific portion of the
// context.
//
NTSTATUS MRxDAVFormatTheDAVContext( PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext, USHORT EntryPoint );
NTSTATUS DavXxxInformation( IN const int xMajorFunction, IN PFILE_OBJECT FileObject, IN ULONG InformationClass, IN ULONG Length, OUT PVOID Information, OUT PULONG ReturnedLength );
ULONG DavReadWriteFileEx( IN USHORT Operation, IN BOOL NonPagedBuffer, IN BOOL UseOriginalIrpsMDL, IN PMDL OriginalIrpsMdl, IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN ULONGLONG FileOffset, IN OUT PVOID DataBuffer, IN ULONG SizeInBytes, OUT PIO_STATUS_BLOCK IoStatusBlock );
NTSTATUS DavReadWriteIrpCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP CalldownIrp, IN PVOID Context );
NTSTATUS MRxDAVProbeForReadWrite( IN PBYTE BufferToBeValidated, IN DWORD BufferSize, IN BOOL doProbeForRead, IN BOOL doProbeForWrite );
NTSTATUS MRxDAVFsCtl( IN OUT PRX_CONTEXT RxContext );
NTSTATUS MRxDAVIsValidDirectory( IN OUT PRX_CONTEXT RxContext, IN PUNICODE_STRING DirectoryName );
NTSTATUS MRxDAVCancelRoutine( PRX_CONTEXT RxContext );
VOID MRxDAVTimeOutTheContexts( BOOL WindDownAllContexts );
VOID MRxDAVContextTimerThread( PVOID DummyContext );
NTSTATUS MRxDAVQueryEaInformation ( IN OUT PRX_CONTEXT RxContext ); NTSTATUS MRxDAVSetEaInformation ( IN OUT PRX_CONTEXT RxContext ); NTSTATUS MRxDAVGetFullParentDirectoryPath( PRX_CONTEXT RxContext, PUNICODE_STRING ParentDirName );
NTSTATUS MRxDAVGetFullDirectoryPath( PRX_CONTEXT RxContext, PUNICODE_STRING FileName, PUNICODE_STRING DirName );
NTSTATUS MRxDAVCreateEncryptedDirectoryKey( PUNICODE_STRING DirName );
NTSTATUS MRxDAVRemoveEncryptedDirectoryKey( PUNICODE_STRING DirName );
NTSTATUS MRxDAVQueryEncryptedDirectoryKey( PUNICODE_STRING DirName );
VOID MRxDAVCleanUpTheLockConflictList( BOOL CleanUpAllEntries );
#endif //_WEBDAV_H
|