|
|
/*
Copyright (c) 1992 Microsoft Corporation
Module Name:
forks.h
Abstract:
This module contains the data structures to handle open forks.
Author:
Jameel Hyder (microsoft!jameelh)
Revision History: 25 Apr 1992 Initial Version
Notes: Tab stop: 4 --*/
#ifndef _FORKS_
#define _FORKS_
// Afp Open modes
#define FORK_OPEN_NONE 0x00
#define FORK_OPEN_READ 0x01
#define FORK_OPEN_WRITE 0x02
#define FORK_OPEN_READWRITE 0x03
#define FORK_OPEN_MASK 0x03
// The Deny mode values are shifted left 2 bits and or'd with the open modes
// in AfpOpenFork() API.
#define FORK_DENY_SHIFT 4
#define FORK_DENY_NONE 0x00
#define FORK_DENY_READ 0x01
#define FORK_DENY_WRITE 0x02
#define FORK_DENY_ALL 0x03
#define FORK_DENY_MASK 0x03
// AfpOpenFork SubFunction values
#define FORK_DATA 0
#define FORK_RSRC 0x80
#define AFP_UNLOCK_FLAG 1
#define AFP_END_FLAG 0x80
/*
* A ForkLock describes a lock on the fork. The locks are anchored at the * OpenForkDesc structure. The list describes all locks for this fork by * all sessions and all OForkRefNums. flo_key and flo_OForkRefNum identifies * the lock uniquely. */ #if DBG
#define FORKLOCK_SIGNATURE *(DWORD *)"FLO"
#define VALID_FORKLOCK (((pForkLock) != NULL) && \
((pForkLock)->Signature == FORKLOCK_SIGNATURE)) #else
#define VALID_FORKLOCK ((pForkLock) != NULL)
#endif
// Forward reference for the ForkLock structure
struct _OpenForkEntry;
typedef struct _ForkLock { #if DBG
DWORD Signature; DWORD QuadAlign1; #endif
struct _ForkLock * flo_Next; // ForkDesc links
struct _OpenForkEntry * flo_pOpenForkEntry; DWORD QuadAlign2; // The owning OFE for this lock
LONG flo_Offset; // Beginning of lock
LONG flo_Size; // Size of lock
DWORD flo_Key; // Key for this lock, essentially the
// SessionId from the SDA
} FORKLOCK, *PFORKLOCK;
/*
* An OpenForkDesc represents an open-fork. The list is anchored at the volume * Descriptor. There is exactly one entry per file/fork. Multiple instances of * open just ups the reference count. The list of locks originating here is for * all instances. A back link to the Volume descriptor exists for comfort. */ #if DBG
#define OPENFORKDESC_SIGNATURE *(DWORD *)"OFD"
#define VALID_OPENFORKDESC(pOpenForkDesc) (((pOpenForkDesc) != NULL) && \
((pOpenForkDesc)->Signature == OPENFORKDESC_SIGNATURE)) #else
#define VALID_OPENFORKDESC(pOpenForkDesc) ((pOpenForkDesc) != NULL)
#endif
typedef struct _OpenForkDesc { #if DBG
DWORD Signature; DWORD QuadAlign1; #endif
struct _OpenForkDesc * ofd_Next; // Volume links
struct _OpenForkDesc ** ofd_Prev; // Volume links
struct _VolDesc * ofd_pVolDesc; // Pointer to the volume descriptor
PFORKLOCK ofd_pForkLock; // List of file locks
DWORD ofd_FileNumber; // File number of the open file
LONG ofd_UseCount; // Number of OpenForkEntry refs.
USHORT ofd_cOpenR; // # of instances of open for read
USHORT ofd_cOpenW; // # of instances of open for write
USHORT ofd_cDenyR; // # of instances of deny read
USHORT ofd_cDenyW; // # of instances of deny write
USHORT ofd_NumLocks; // Number of file locks
USHORT ofd_Flags; // OPEN_FORK_xxx bits
AFP_SPIN_LOCK ofd_Lock; // Lock for this descriptor
UNICODE_STRING ofd_FileName; // Name of the file (w/o the stream)
UNICODE_STRING ofd_FilePath; // Volume relative path to the file
} OPENFORKDESC, *POPENFORKDESC;
#define OPEN_FORK_RESOURCE True
#define OPEN_FORK_DATA False
#define OPEN_FORK_CLOSING 0x8000
// To determine whether FlushFork of resource should really take the current
// ChangeTime to be the LastWriteTime
#define OPEN_FORK_WRITTEN 0x0100
/*
* An OpenForkEntry represents an OForkRefNum. Every instance of an open * fork has an entry here. This list is anchored in the SDA. A global open * fork list used by the admin APIs is also linked to this. */ #if DBG
#define OPENFORKENTRY_SIGNATURE *(DWORD *)"OFE"
#define VALID_OPENFORKENTRY(pOpenForkEntry) \
(((pOpenForkEntry) != NULL) && \ ((pOpenForkEntry)->Signature == OPENFORKENTRY_SIGNATURE)) #else
#define VALID_OPENFORKENTRY(pOpenForkEntry) ((pOpenForkEntry) != NULL)
#endif
typedef struct _OpenForkEntry { #if DBG
DWORD Signature; #endif
struct _OpenForkEntry * ofe_Next; // Global links
struct _OpenForkEntry **ofe_Prev; // Global links
struct _OpenForkDesc * ofe_pOpenForkDesc; // Pointer to the descriptor
struct _SessDataArea * ofe_pSda; // Identifies the owning session
struct _ConnDesc * ofe_pConnDesc; // Identifies the owning connection
FILESYSHANDLE ofe_FileSysHandle; // The file system handles
#define ofe_ForkHandle ofe_FileSysHandle.fsh_FileHandle
#define ofe_pFileObject ofe_FileSysHandle.fsh_FileObject
#define ofe_pDeviceObject ofe_FileSysHandle.fsh_DeviceObject
DWORD ofe_OForkRefNum; // Open Fork reference number
DWORD ofe_ForkId; // Unique file id used by admin.
// Not re-cycled
BYTE ofe_OpenMode; // Open modes - AFP
BYTE ofe_DenyMode; // Deny modes - AFP
USHORT ofe_Flags; // Flag bits defined above
LONG ofe_RefCount; // Count of references to this entry
LONG ofe_cLocks; // Number of locks on this fork
AFP_SPIN_LOCK ofe_Lock; // Lock for manipulating locks etc.
} OPENFORKENTRY, *POPENFORKENTRY;
#define RESCFORK(pOpenForkEntry) \
(((pOpenForkEntry)->ofe_Flags & OPEN_FORK_RESOURCE) ? True : False)
#define DATAFORK(pOpenForkEntry) (!RESCFORK(pOpenForkEntry))
#define FORK_OPEN_CHUNKS 7
typedef struct _OpenForkSession { POPENFORKENTRY ofs_pOpenForkEntry[FORK_OPEN_CHUNKS]; // Pointer to actual entry
struct _OpenForkSession *ofs_Link; // Link to next cluster
} OPENFORKSESS, *POPENFORKSESS;
// Used by AfpForkLockOperation call.
typedef enum { LOCK = 1, UNLOCK, IOCHECK, } LOCKOP;
GLOBAL POPENFORKENTRY AfpOpenForksList EQU NULL; // List of open forks
GLOBAL DWORD AfpNumOpenForks EQU 0; // Total # of open forks
GLOBAL AFP_SPIN_LOCK AfpForksLock EQU { 0 }; // Lock for AfpOpenForksList,
// and AfpNumOpenForks
extern NTSTATUS AfpForksInit( VOID );
extern POPENFORKENTRY FASTCALL AfpForkReferenceByRefNum( IN struct _SessDataArea * pSda, IN DWORD OForkRefNum );
extern POPENFORKENTRY FASTCALL AfpForkReferenceByPointer( IN POPENFORKENTRY pOpenForkEntry );
extern POPENFORKENTRY FASTCALL AfpForkReferenceById( IN DWORD ForkId );
extern VOID FASTCALL AfpForkDereference( IN POPENFORKENTRY pOpenForkEntry );
extern AFPSTATUS AfpForkOpen( IN struct _SessDataArea * pSda, IN struct _ConnDesc * pConnDesc, IN struct _PathMapEntity * pPME, IN struct _FileDirParms * pFDParm, IN DWORD AccessMode, IN BOOLEAN Resource, OUT POPENFORKENTRY * ppOpenForkEntry, OUT PBOOLEAN pCleanupExchgLock );
extern VOID AfpForkClose( IN POPENFORKENTRY pOpenForkEntry );
extern AFPSTATUS AfpCheckDenyConflict( IN struct _VolDesc * pVolDesc, IN DWORD AfpId, IN BOOLEAN Resource, IN BYTE OpenMode, IN BYTE DenyMode, IN POPENFORKDESC * ppOpenForkDesc OPTIONAL );
extern AFPSTATUS AfpForkLockOperation( IN struct _SessDataArea * pSda, IN POPENFORKENTRY pOpenForkEntry, IN OUT PFORKOFFST pOffset, IN OUT PFORKSIZE pSize, IN LOCKOP Operation, // LOCK, UNLOCK or IOCHECK
IN BOOLEAN EndFlag // If True range is from end, else start
);
extern VOID AfpForkLockUnlink( IN PFORKLOCK pForkLock );
extern AFPSTATUS AfpAdmWForkClose( IN OUT PVOID InBuf OPTIONAL, IN LONG OutBufLen OPTIONAL, OUT PVOID OutBuf OPTIONAL );
extern VOID AfpExchangeForkAfpIds( IN struct _VolDesc * pVolDesc, IN DWORD AfpId1, IN DWORD AfpId2 );
#ifdef FORK_LOCALS
LOCAL DWORD afpNextForkId = 1; // Id to be assigned to an open fork
LOCAL BOOLEAN afpForkGetNewForkRefNumAndLinkInSda( IN struct _SessDataArea * pSda, IN POPENFORKENTRY pOpenForkEntry );
LOCAL AFPSTATUS afpForkConvertToAbsOffSize( IN POPENFORKENTRY pOpenForkEntry, IN LONG Offset, IN OUT PLONG pSize, OUT PFORKOFFST pAbsOffset );
#endif // FORK_LOCALS
#endif // _FORKS_
|