889 lines
23 KiB
C
889 lines
23 KiB
C
/*++
|
|
|
|
FILEHC.H
|
|
|
|
This file defines the public interfaces for issuing async Reads/Writes to a file
|
|
using the fileh wrapper library.
|
|
|
|
--*/
|
|
|
|
#ifndef _FILEHC_H_
|
|
#define _FILEHC_H_
|
|
|
|
// Published parts of the File Handle cache !
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef VOID
|
|
(*PFN_IO_COMPLETION)(
|
|
IN struct FIO_CONTEXT* pContext,
|
|
IN struct FH_OVERLAPPED* lpo,
|
|
IN DWORD cb,
|
|
IN DWORD dwCompletionStatus
|
|
);
|
|
|
|
|
|
|
|
struct FH_OVERLAPPED {
|
|
/*++
|
|
|
|
This structure defines the extended OVERLAPPED structure
|
|
used by the File IO layer implemented in this module.
|
|
|
|
The first 5 elements of this structure are identical to
|
|
NT's OVERLAPPED structure and have the exact same semantics.
|
|
|
|
The final additional parameter is a pointer to a
|
|
function that will be called to complete the IO.
|
|
|
|
--*/
|
|
UINT_PTR Internal ;
|
|
UINT_PTR InternalHigh ;
|
|
DWORD Offset ;
|
|
DWORD OffsetHigh ;
|
|
HANDLE hEvent ;
|
|
PFN_IO_COMPLETION pfnCompletion ;
|
|
UINT_PTR Reserved1 ;
|
|
UINT_PTR Reserved2 ;
|
|
UINT_PTR Reserved3 ;
|
|
UINT_PTR Reserved4 ;
|
|
} ;
|
|
|
|
typedef struct FH_OVERLAPPED* PFH_OVERLAPPED ;
|
|
|
|
struct FIO_CONTEXT {
|
|
/*++
|
|
|
|
This structure defines the context object
|
|
that is used to represent file handles.
|
|
|
|
--*/
|
|
//
|
|
// Temporary hack - mailmsg object assumes it can put a NULL in us !
|
|
//
|
|
DWORD m_dwTempHack ;
|
|
|
|
//
|
|
// The context signature !
|
|
//
|
|
DWORD m_dwSignature ;
|
|
|
|
//
|
|
// The users file handle !
|
|
//
|
|
HANDLE m_hFile ;
|
|
|
|
//
|
|
// The offset to back fill Lines header - nntp aware only
|
|
//
|
|
DWORD m_dwLinesOffset;
|
|
|
|
//
|
|
// Header length - nntp aware only
|
|
//
|
|
DWORD m_dwHeaderLength;
|
|
} ;
|
|
|
|
typedef FIO_CONTEXT* PFIO_CONTEXT ;
|
|
|
|
|
|
#ifdef _FILEHC_IMPLEMENTATION_
|
|
#define FILEHC_EXPORT __declspec( dllexport )
|
|
#else
|
|
#define FILEHC_EXPORT __declspec( dllimport )
|
|
#endif
|
|
|
|
|
|
//
|
|
// Initialize the DLL for Async IO -
|
|
// This is a counting initialize - for each call to FIOInitialize()
|
|
// there should be a matching call to FIOTerminate
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOInitialize(
|
|
IN DWORD dwFlags
|
|
);
|
|
|
|
//
|
|
// Terminate the DLL's support for Async IO !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOTerminate(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Do an async read against the File !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOReadFile(
|
|
IN PFIO_CONTEXT pContext,
|
|
IN LPVOID lpBuffer,
|
|
IN DWORD BytesToRead,
|
|
IN FH_OVERLAPPED * lpo
|
|
);
|
|
|
|
//
|
|
// Do an async read against the file - pass extra args
|
|
// so that if the FIO_CONTEXT is doing dot stuffing for the user
|
|
// it can do so efficiently !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOReadFileEx(
|
|
IN PFIO_CONTEXT pContext,
|
|
IN LPVOID lpBuffer,
|
|
IN DWORD BytesToRead,
|
|
IN DWORD BytesAvailable, // must be >= BytesToWrite - number of bytes I can mess with.
|
|
IN FH_OVERLAPPED * lpo,
|
|
IN BOOL fFinalWrite, // Is this the final write ?
|
|
IN BOOL fIncludeTerminator // if TRUE contains CRLF.CRLF terminator which shouldn't be stuffed
|
|
);
|
|
|
|
|
|
//
|
|
// Do an async write against the file !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOWriteFile(
|
|
IN PFIO_CONTEXT pContext,
|
|
IN LPCVOID lpBuffer,
|
|
IN DWORD BytesToWrite,
|
|
IN FH_OVERLAPPED * lpo
|
|
);
|
|
|
|
//
|
|
// Do an async write against the file - pass extra args
|
|
// so that if the FIO_CONTEXT is doing dot stuffing for the user
|
|
// it can do so efficiently !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FIOWriteFileEx(
|
|
IN PFIO_CONTEXT pContext,
|
|
IN LPVOID lpBuffer,
|
|
IN DWORD BytesToWrite,
|
|
IN DWORD BytesAvailable, // must be >= BytesToWrite - number of bytes I can mess with.
|
|
IN FH_OVERLAPPED* lpo,
|
|
IN BOOL fFinalWrite, // Is this the final write ?
|
|
IN BOOL fIncludeTerminator // if TRUE contains CRLF.CRLF terminator which shouldn't be stuffed
|
|
) ;
|
|
|
|
//
|
|
// Callback functions which create things in the cache !
|
|
//
|
|
// NOTE: this is equivalent to FCACHE_RICHCREATE_CALLBACK where
|
|
//
|
|
// pfDidWeScanIt - returns FALSE
|
|
// pfIsStuffed - return FALSE
|
|
// pfStoredWithDots - return FALSE
|
|
//
|
|
typedef
|
|
HANDLE
|
|
(__stdcall *FCACHE_CREATE_CALLBACK) (
|
|
IN LPSTR lpstrName,
|
|
IN LPVOID lpvData,
|
|
OUT DWORD* cbFileSize,
|
|
OUT DWORD* cbFileSizeHigh
|
|
) ;
|
|
|
|
|
|
//
|
|
// Callback functions which create things in the cache !
|
|
//
|
|
// This function will be called by CacheRichCreateFile().
|
|
//
|
|
// lpstrName - the name of the file
|
|
// lpvData - User provided data, provided to CacheRichCreateFile
|
|
// cbFileSize - The function should return the size of the file through this
|
|
// cbFileSizeHigh - place to return the High DWORD of the file size
|
|
// pfDidWeScanIt - if THIS is true then at some point the created file has been
|
|
// scanned for DOTs appearing at the beginning of lines
|
|
// pfIsStuffed - This is only meaningfull if pfDidWeScanIt==TRUE, in which case
|
|
// if this is TRUE this indicates that there are DOTs at the beginning of lines
|
|
// pfStoredWithDots - If this is TRUE then it indicates that any DOTs that appear
|
|
// at the beginning of lines are stored with an extra dot as required in NNTP,
|
|
// SMTP and POP3 protocols. if this is FALSE then the message is stored without
|
|
// DOT stuffing.
|
|
//
|
|
typedef
|
|
HANDLE
|
|
(__stdcall *FCACHE_RICHCREATE_CALLBACK) (
|
|
IN LPSTR lpstrName,
|
|
IN LPVOID lpvData,
|
|
OUT DWORD* cbFileSize,
|
|
OUT DWORD* cbFileSizeHigh,
|
|
OUT BOOL* pfDidWeScanIt,
|
|
OUT BOOL* pfIsStuffed,
|
|
OUT BOOL* pfStoredWithDots,
|
|
OUT BOOL* pfStoredWithTerminatingDot
|
|
) ;
|
|
|
|
//
|
|
// Initialize the File Handle Cache -
|
|
//
|
|
// NOTE : this will automatically initialize the DLL for async
|
|
// IO as well !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
InitializeCache() ;
|
|
|
|
//
|
|
// Terminate the cache !
|
|
//
|
|
// NOTE : this will terminate the DLL for async IO as well !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
TerminateCache() ;
|
|
|
|
//
|
|
// Associate a file with an async context !
|
|
//
|
|
FILEHC_EXPORT
|
|
PFIO_CONTEXT __stdcall
|
|
AssociateFile( HANDLE hFile ) ;
|
|
|
|
//
|
|
// This allows the user to specify whether file stores content with extra DOTS
|
|
// added for RFC 822 protocols (i.e. NNTP and SMTP DATA commands).
|
|
//
|
|
// NOTE: AssociateFile() is the same as AssociateFileEx( hFile, FALSE ) ;
|
|
//
|
|
// hFile - The file that contains message content, or in which we will write message content
|
|
// fStoreWithDots - if TRUE then each period or DOT in the file which starts a line
|
|
// but is NOT part of the terminating CRLF.CRLF will be stored with an extra dot
|
|
// adjacent to it. This is the on the wire format for NNTP for instance.
|
|
//
|
|
FILEHC_EXPORT
|
|
PFIO_CONTEXT __stdcall
|
|
AssociateFileEx( HANDLE hFile,
|
|
BOOL fStoreWithDots,
|
|
BOOL fStoredWithTerminatingDot
|
|
) ;
|
|
|
|
//
|
|
// Add a reference to a context -
|
|
//
|
|
// Each call to AddRefContext() must be matched by a corresponding
|
|
// call to ReleaseContext(). Both AssociateFile and CacheCreateFile()
|
|
// also add a single reference which must be matched by a call to ReleaseContext().
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
AddRefContext( PFIO_CONTEXT ) ;
|
|
|
|
//
|
|
// Release a Context !
|
|
//
|
|
// FIO_CONTEXT's are reference counted - the user must call
|
|
// this for each successfull call to CacheCreateFile(), and
|
|
// each call to InsertFile() where fKeepReference is TRUE
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
ReleaseContext( PFIO_CONTEXT ) ;
|
|
|
|
//
|
|
// Close a handle associated with a non-cached FIO_CONTEXT
|
|
//
|
|
// This is used to Close the file handle within a context.
|
|
// This only succeeds if the FIO_CONTEXT is not cached !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
CloseNonCachedFile( PFIO_CONTEXT ) ;
|
|
|
|
//
|
|
// Create a file in the cache, or find an existing one !
|
|
//
|
|
// If the file is not in the cache, the cache will call
|
|
// pfnCallBack with lpv to do the actual work of calling
|
|
// CreateFile().
|
|
//
|
|
FILEHC_EXPORT
|
|
FIO_CONTEXT* __stdcall
|
|
CacheCreateFile( IN LPSTR lpstrName,
|
|
IN FCACHE_CREATE_CALLBACK pfnCallBack,
|
|
IN LPVOID lpv,
|
|
IN BOOL fAsyncContext
|
|
) ;
|
|
|
|
//
|
|
// Create a file in the cache or find an existing one,
|
|
// if we create the file we can add properties onto it in
|
|
// the cache !
|
|
//
|
|
FILEHC_EXPORT
|
|
FIO_CONTEXT* __stdcall
|
|
CacheRichCreateFile( IN LPSTR lpstrName,
|
|
IN FCACHE_RICHCREATE_CALLBACK pfnCallBack,
|
|
IN LPVOID lpv,
|
|
IN BOOL fAsyncContext
|
|
) ;
|
|
|
|
//
|
|
// This function allows a user to remove all files with the specified
|
|
// Name from the cache. if fAllPrefixes is TRUE, we will remove all files
|
|
// where the Name matches the beginning of the path !
|
|
// If fAllPrefixes is FALSE then we will remove only the one file which
|
|
// exactly matches lpstrName !
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
CacheRemoveFiles( IN LPSTR lpstrName,
|
|
IN BOOL fAllPrefixes
|
|
) ;
|
|
//
|
|
// Insert the file into the cache !
|
|
//
|
|
// This function will add the file handle in the FIO_CONTEXT
|
|
// to the cache. All searches by lpstrName will find this
|
|
// item untill it expires from the cache.
|
|
//
|
|
// If fKeepReference is TRUE then the user must make a call to
|
|
// ReleaseContext() for the inserted FIO_CONTEXT !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
InsertFile( IN LPSTR lpstrName,
|
|
IN FIO_CONTEXT* pContext,
|
|
IN BOOL fKeepReference
|
|
) ;
|
|
|
|
//
|
|
// Report the file size that we've cached with the handle
|
|
//
|
|
FILEHC_EXPORT
|
|
DWORD __stdcall
|
|
GetFileSizeFromContext( IN FIO_CONTEXT* pContext,
|
|
OUT DWORD* pcbFileSizeHigh
|
|
) ;
|
|
|
|
//----------------------------------------------------------------------
|
|
// NAME CACHE NAME CACHE NAME CACHE -
|
|
//
|
|
// Name Cache API's
|
|
//
|
|
//
|
|
|
|
//
|
|
// This is the function pointer provided by clients to compare
|
|
// keys. This must be provided on all calls.
|
|
//
|
|
// The function has memcmp() semantics, i.e. it must order the keys
|
|
// consistently, and return <0 if key1 is smaller then key2, ==0 if the
|
|
// keys match and >0 if key1 is greater then key2.
|
|
//
|
|
typedef
|
|
int
|
|
(__stdcall *CACHE_KEY_COMPARE)( IN DWORD cbKey1,
|
|
IN LPBYTE lpbKey1,
|
|
IN DWORD cbKey2,
|
|
IN LPBYTE lpbKey2
|
|
) ;
|
|
|
|
//
|
|
// This is the function provided by clients to compute a hash
|
|
// value on Keys - NOTE: The Cache will provide a hash function
|
|
// IF the user does not, however the internally provided hash
|
|
// function is best only for things that appear to be regular strings.
|
|
//
|
|
typedef
|
|
DWORD
|
|
(__stdcall *CACHE_KEY_HASH)( IN LPBYTE lpbKey,
|
|
IN DWORD cbKey
|
|
) ;
|
|
|
|
//
|
|
// This is the generic callback function that is provided to the
|
|
// cache to help examine items within the cache.
|
|
// The BOOL return value is meaningfull to the Cache API's only
|
|
// on the following calls :
|
|
//
|
|
//
|
|
typedef
|
|
BOOL
|
|
(__stdcall *CACHE_READ_CALLBACK)( IN DWORD cb,
|
|
IN LPBYTE lpb,
|
|
IN LPVOID lpvContext
|
|
) ;
|
|
|
|
//
|
|
// This is a callback that is called whenever we destroy an entry in
|
|
// the name cache - this is called once for both key and data components,
|
|
// and gives the client a chance to track any relationships
|
|
//
|
|
// NOTE : if the client does not associate
|
|
// data with the name, the function will only be called for the Key data.
|
|
//
|
|
typedef
|
|
void
|
|
(__stdcall *CACHE_DESTROY_CALLBACK)( IN DWORD cb,
|
|
IN LPBYTE lpb
|
|
) ;
|
|
|
|
//
|
|
// This is a callback this is called whenever we evaluate a security descriptor.
|
|
// If it is not provided we will call the standard NT AccessCheck() call !
|
|
//
|
|
// The function has the same signature as AccessCheck, however there are arguments
|
|
// we don't use - PrivilegeSet will always be NULL and PrivilegeSetLength will always be 0 !
|
|
//
|
|
typedef
|
|
BOOL
|
|
(WINAPI *CACHE_ACCESS_CHECK)( IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
|
IN HANDLE hClientToken,
|
|
IN DWORD dwDesiredAccess,
|
|
IN PGENERIC_MAPPING GenericMapping,
|
|
IN PRIVILEGE_SET* PrivilegeSet,
|
|
IN LPDWORD PrivilegeSetLength,
|
|
IN LPDWORD GrantedAccess,
|
|
IN LPBOOL AccessStatus
|
|
) ;
|
|
|
|
|
|
//
|
|
// This is the externally exposed structure representing a Name Cache -
|
|
// it doesn't contain any fields usefull for a client, but must be passed
|
|
// back into all of the name cache API's
|
|
//
|
|
struct NAME_CACHE_CONTEXT {
|
|
//
|
|
// Signature DWORD ! - user must not touch this !
|
|
//
|
|
DWORD m_dwSignature ;
|
|
} ;
|
|
|
|
typedef struct NAME_CACHE_CONTEXT* PNAME_CACHE_CONTEXT ;
|
|
|
|
//
|
|
// API's for creating/manging NAME CACHE's
|
|
// NOTE : Name Cache's are reference counted, and if this
|
|
// function is called twice with the same name we will
|
|
// Add a reference to an existing Name Cache.
|
|
//
|
|
FILEHC_EXPORT
|
|
PNAME_CACHE_CONTEXT __stdcall
|
|
FindOrCreateNameCache(
|
|
//
|
|
// Must not be NULL ! - this is CASE SENSITVE !
|
|
//
|
|
LPSTR lpstrName,
|
|
//
|
|
// Must not be NULL !
|
|
//
|
|
CACHE_KEY_COMPARE pfnKeyCompare,
|
|
//
|
|
// This may be NULL, in which case the cache will provide one !
|
|
//
|
|
CACHE_KEY_HASH pfnKeyHash,
|
|
//
|
|
// The following two function pointers may be NULL !
|
|
//
|
|
CACHE_DESTROY_CALLBACK pfnKeyDestroy,
|
|
CACHE_DESTROY_CALLBACK pfnDataDestroy
|
|
) ;
|
|
|
|
//
|
|
// API's for releasing the NAME CACHE !
|
|
//
|
|
// The caller must guarantee the thread safety of this call - This function must not
|
|
// be called if any other thread is simultanesouly executing within
|
|
// CacheFindContectFromName(), AssociateContextWithName(), AssociateDataWithName(), or InvalidateName()
|
|
//
|
|
FILEHC_EXPORT
|
|
long __stdcall
|
|
ReleaseNameCache(
|
|
//
|
|
// Must not be NULL !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache
|
|
) ;
|
|
|
|
|
|
//
|
|
// API's for setting options on the name cache - this can be used to change
|
|
// how Security is evaluated !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
SetNameCacheSecurityFunction(
|
|
//
|
|
// Must not be NULL !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache,
|
|
//
|
|
// This is the function pointer that will be used to evaluate security -
|
|
// this may be NULL - if it is we will use the Win32 Access Check !
|
|
//
|
|
CACHE_ACCESS_CHECK pfnAccessCheck
|
|
) ;
|
|
|
|
//
|
|
// Find the FIO_CONTEXT that is associated with some user name.
|
|
//
|
|
// The function returns TRUE if the Name was found in the cache.
|
|
// FALSE if the name was not found in the cache.
|
|
//
|
|
// If the function returns FALSE then the pfnCallback function will not be
|
|
// called.
|
|
//
|
|
// If the function returns TRUE, ppFIOContext may return a NULL pointer,
|
|
// if the user passed a NULL FIO_CONTEXT to AssociateContextWithName() !
|
|
//
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FindContextFromName(
|
|
//
|
|
// The name cache the client wishes to use !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache,
|
|
//
|
|
// User provides arbitrary bytes for Key to the cache item - pfnKeyCompare() used
|
|
// to compare keys !
|
|
//
|
|
IN LPBYTE lpbName,
|
|
IN DWORD cbName,
|
|
//
|
|
// User provides function which is called with the key once the key comparison
|
|
// matches the key. This lets the user do some extra checking that they're getting
|
|
// what they want.
|
|
//
|
|
IN CACHE_READ_CALLBACK pfnCallback,
|
|
IN LPVOID lpvClientContext,
|
|
//
|
|
// Ask the cache to evaluate the embedded security descriptor
|
|
// if hToken is 0 then we ignore and security descriptor data
|
|
//
|
|
IN HANDLE hToken,
|
|
IN ACCESS_MASK accessMask,
|
|
//
|
|
// We have a separate mechanism for returning the FIO_CONTEXT
|
|
// from the cache.
|
|
//
|
|
OUT FIO_CONTEXT** ppContext
|
|
) ;
|
|
|
|
|
|
//
|
|
// Find the FIO_CONTEXT that is associated with some user name.
|
|
//
|
|
// The function returns TRUE if the Name was found in the cache.
|
|
// FALSE if the name was not found in the cache.
|
|
//
|
|
// If the function returns FALSE then the pfnCallback function will not be
|
|
// called.
|
|
//
|
|
// If the function returns TRUE, ppFIOContext may return a NULL pointer,
|
|
// if the user passed a NULL FIO_CONTEXT to AssociateContextWithName() !
|
|
//
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
FindSyncContextFromName(
|
|
//
|
|
// The name cache the client wishes to use !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache,
|
|
//
|
|
// User provides arbitrary bytes for Key to the cache item - pfnKeyCompare() used
|
|
// to compare keys !
|
|
//
|
|
IN LPBYTE lpbName,
|
|
IN DWORD cbName,
|
|
//
|
|
// User provides function which is called with the key once the key comparison
|
|
// matches the key. This lets the user do some extra checking that they're getting
|
|
// what they want.
|
|
//
|
|
IN CACHE_READ_CALLBACK pfnCallback,
|
|
IN LPVOID lpvClientContext,
|
|
//
|
|
// Ask the cache to evaluate the embedded security descriptor
|
|
// if hToken is 0 then we ignore and security descriptor data
|
|
//
|
|
IN HANDLE hToken,
|
|
IN ACCESS_MASK accessMask,
|
|
//
|
|
// We have a separate mechanism for returning the FIO_CONTEXT
|
|
// from the cache.
|
|
//
|
|
OUT FIO_CONTEXT** ppContext
|
|
) ;
|
|
|
|
|
|
//
|
|
// Cache Associate context with name !
|
|
// This insert a Name into the Name cache, that will find the specified FIO_CONTEXT !
|
|
//
|
|
// If the name is already present in the cache, this will fail with GetLastError()==ERROR_DUP_NAME !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
AssociateContextWithName(
|
|
//
|
|
// The name cache the client wishes to use !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache,
|
|
//
|
|
// User provides arbitrary bytes for the Name of the cache item.
|
|
//
|
|
IN LPBYTE lpbName,
|
|
IN DWORD cbName,
|
|
//
|
|
// User may provide some arbitrary data to assoicate with the name !
|
|
//
|
|
IN LPBYTE lpbData,
|
|
IN DWORD cbData,
|
|
//
|
|
// User may provide a self relative security descriptor to
|
|
// be associated with the name !
|
|
//
|
|
IN PGENERIC_MAPPING pGenericMapping,
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
|
//
|
|
// User provides the FIO_CONTEXT that the name should reference
|
|
//
|
|
FIO_CONTEXT* pContext,
|
|
//
|
|
// User specifies whether they wish to keep their reference on the FIO_CONTEXT
|
|
//
|
|
BOOL fKeepReference
|
|
) ;
|
|
|
|
//
|
|
// This function allows the user to remove a single name and all associated data
|
|
// from the name cache.
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL
|
|
InvalidateName(
|
|
//
|
|
// The name cache the client wishes to use !
|
|
//
|
|
PNAME_CACHE_CONTEXT pNameCache,
|
|
//
|
|
// User provides arbitrary bytes for the Name of the cache item.
|
|
//
|
|
IN LPBYTE lpbName,
|
|
IN DWORD cbName
|
|
) ;
|
|
|
|
|
|
//
|
|
// End of Name Cache API's
|
|
//----------------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// DOT STUFFING API's
|
|
//
|
|
|
|
//
|
|
// This function gets an FIO_CONTEXT with the requested state.
|
|
// We may or may not create a new FIO_CONTEXT, if we do create one we'll stick
|
|
// it into the cache so it can be used again !
|
|
// NOTE: if we have to do work, the user has the only reference to the resulting
|
|
// FIO_CONTEXT which will go away when they call ReleaseContext() !
|
|
//
|
|
// pContext - the original FIO_CONTEXT
|
|
// lpstrName - the file name associated with pContext
|
|
// fWantItDotStuffed - if TRUE the resulting FIO_CONTEXT should be dot stuffed !
|
|
// fTerminatorIncluded - if this is TRUE the source FIO_CONTEXT contains a terminating
|
|
// dot that we should be carefull not to stuff !
|
|
//
|
|
// NOTE: We may return the same FIO_CONTEXT as the caller provided - in which case
|
|
// an extra reference has been added that needs to be dropped with ReleaseContext() !
|
|
//
|
|
//
|
|
FILEHC_EXPORT
|
|
FIO_CONTEXT* __stdcall
|
|
ProduceDotStuffedContext( IN FIO_CONTEXT* pContext,
|
|
IN LPSTR lpstrName,
|
|
IN BOOL fWantItDotStuffed // if TRUE add dots, if FALSE remove dots
|
|
) ;
|
|
|
|
//
|
|
// This function takes a source FIO_CONTEXT (pContextSource) and copies
|
|
// the content into pContextDestination.
|
|
//
|
|
// The user specifies whether the Destination FIO_CONTEXT should be dot stuffed
|
|
// with fWantItDotStuffed, and whether the source FIO_CONTEXT includes the
|
|
// terminating CRLF.CRLF
|
|
//
|
|
// The out parameter pfModified is TRUE if there were modifications when
|
|
// Source was copied to Destination !
|
|
//
|
|
// The function returns TRUE if successfull, FALSE otherwise !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
ProduceDotStuffedContextInContext(
|
|
IN FIO_CONTEXT* pContextSource,
|
|
IN FIO_CONTEXT* pContextDestination,
|
|
IN BOOL fWantItDotStuffed,
|
|
OUT BOOL* pfModified
|
|
) ;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Find out whether the file has a terminating 'CRLF.CRLF' sequence !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
GetIsFileDotTerminated( IN FIO_CONTEXT* pContext ) ;
|
|
|
|
//
|
|
// Set whether the file has a terminating 'CRLF.CRLF' sequence !
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
SetIsFileDotTerminated( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fIsDotTerminated
|
|
) ;
|
|
|
|
//
|
|
// Enable dot stuffing properties on the write path of the file
|
|
// handle cache of this message !
|
|
//
|
|
// if fEnable is FALSE then all dot stuffing behaviour is turned
|
|
// off.
|
|
//
|
|
// if fStripDots is TRUE the File Handle Cache will convert
|
|
// occurrences of "\r\n." to "\r\n" within your message.
|
|
//
|
|
// if fStripDots is FALSE the FileHandle Cache will convert occurrences
|
|
// of "\r\n.." to "\r\n" within your message.
|
|
//
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
SetDotStuffingOnWrites( IN FIO_CONTEXT* pContext,
|
|
//
|
|
// fEnable == FALSE means ignore fStripDots, and writes are unmodified
|
|
//
|
|
IN BOOL fEnable,
|
|
//
|
|
// fStripDots == TRUE means we remove dots that are dot stuffed,
|
|
// fStripDots == FALSE means that we add dots to make the message dot stuffed
|
|
//
|
|
IN BOOL fStripDots
|
|
) ;
|
|
|
|
#if 0
|
|
//
|
|
// This function temporarily disabled !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
SetDotStuffingOnReads( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fEnable,
|
|
IN BOOL fStripDots
|
|
) ;
|
|
#endif
|
|
|
|
//
|
|
// Enable dot scanning properties on the write path
|
|
// of the file handle cache for this file !
|
|
//
|
|
// if fEnable is TRUE the we will examine each write
|
|
// that goes through us to determine whether the
|
|
// message has any occurrences of "\r\n.".
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
SetDotScanningOnWrites( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fEnable
|
|
) ;
|
|
|
|
//
|
|
//
|
|
// This function should be called when we have finished doing all writes to an FIO_CONTEXT
|
|
// This function should be paired with SetDotStuffingOnWrites() and the fStripDots
|
|
// parameter should be the same as when SetDotStuffingOnWrites() was called.
|
|
//
|
|
// We will update the Dot Stuffing State of the FIO_CONTEXT and discard
|
|
// all dot stuffing memory and stuff that may have been required !
|
|
//
|
|
// If this function call is paired with a call to SetDotScanningOnWrites() fStripDots should be TRUE !
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
CompleteDotStuffingOnWrites( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fStripDots
|
|
) ;
|
|
|
|
//
|
|
// This will cause us to examine each read for occurrences of
|
|
// "\r\n."
|
|
//
|
|
// NOTE : the user must use ASYNC Reads for this to work - we will assert
|
|
// if the user tries to pend any synchronous reads while we are in this state !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
SetDotScanningOnReads( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fEnable
|
|
) ;
|
|
|
|
|
|
//
|
|
// If any of the dot stuffing mechanism our turned on,
|
|
// this will get a count of the number of occurrences/modifications
|
|
// have occurred.
|
|
//
|
|
// if fReads is TRUE we get the count for occurrences on Read's
|
|
// if fReads is FALSE we get the count for occurrences on Write's
|
|
//
|
|
// if dot stuffing was turned off or not enabled somehow then
|
|
// GetDotStuffState() will return FALSE.
|
|
//
|
|
// NOTE: A NULL pfStuffed is not allowed !
|
|
//
|
|
FILEHC_EXPORT
|
|
BOOL __stdcall
|
|
GetDotStuffState( IN FIO_CONTEXT* pContext,
|
|
IN BOOL fReads,
|
|
OUT BOOL* pfStuffed,
|
|
OUT BOOL* pfStoredWithDots
|
|
) ;
|
|
|
|
//
|
|
// In this case we always assume that the FIO_CONTEXT is not going to be dot stuffed.
|
|
// fRequiresStuffing == TRUE indicates that it SHOULD BE stuffed.
|
|
// fRequiresStuffing == FALSE indicates that the message does not need dot stuffing.
|
|
//
|
|
FILEHC_EXPORT
|
|
void __stdcall
|
|
SetDotStuffState( IN FIO_CONTEXT* pContext,
|
|
//
|
|
// fIsStuffed is only relevant when fKnown == TRUE
|
|
//
|
|
IN BOOL fKnown, // We do know the dot stuff state
|
|
//
|
|
// if fKnown is TRUE then fIsStuffed is meaningfull, when thats the case
|
|
// if fIsStuffed is TRUE then the message
|
|
//
|
|
IN BOOL fRequiresStuffing// if fKnown is TRUE this arg is meaningfull
|
|
) ;
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#endif // _FILEHC_H_
|