WindowsXP-SP1/ds/ese98/eximport/ifsuser.h

457 lines
14 KiB
C

/*++
Copyright (c) 1989 - 1998 Microsoft Corporation
Module Name:
ifsuser.h
Abstract:
Ifsuser is a static lib that wraps a bunch of user-mode code
needed for using the IFS. It is not necessary to use the APIs
in this lib for availing the IFS functionality. However, using
it will isolate clients from changes to IFS headers / data str.
Applications that do not want to use NtXXX APIs should include
this header file.
Applications that directly use NtXXX APIs only need <exifs.h>
Author:
Rajeev Rajan [RajeevR] 7-Apr-1998
Revision History:
--*/
#ifndef _IFSUSER_H_
#define _IFSUSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef EXIFS_DEVICE_NAME
#define EXIFS_DEVICE_NAME
//////////////////////////////////////////////////////////////////////////////
// The Devicename string required to access the exchange IFS device
// from User-Mode. Clients should use DD_EXIFS_USERMODE_DEV_NAME_U.
//////////////////////////////////////////////////////////////////////////////
// Local store Device names
#define DD_LSIFS_USERMODE_SHADOW_DEV_NAME_U L"\\??\\LocalStoreIfs"
#define DD_LSIFS_USERMODE_DEV_NAME_U L"\\\\.\\LocalStoreIfs"
//
// WARNING The next two strings must be kept in sync. Change one and you must
// change the other. These strings have been chosen such that they are
// unlikely to coincide with names of other drivers.
//
// NOTE: These definitions MUST be synced with <exifs.h>
//
#define DD_EXIFS_USERMODE_SHADOW_DEV_NAME_U L"\\??\\ExchangeIfs"
#define DD_EXIFS_USERMODE_DEV_NAME_U L"\\\\.\\ExchangeIfs"
//
// Prefix needed before <store-name>\<root-name>
//
#define DD_EXIFS_MINIRDR_PREFIX L"\\;E:"
#endif // EXIFS_DEVICE_NAME
//
// Bit flags for PR_DOTSTUFF_STATE
//
// DOTSTUFF_STATE_HAS_BEEN_SCANNED - Has the content been scanned?
// DOTSTUFF_STATE_NEEDS_STUFFING - If it has been scanned does
// it need to be dot stuffed?
#define DOTSTUFF_STATE_HAS_BEEN_SCANNED 0x1
#define DOTSTUFF_STATE_NEEDS_STUFFING 0x2
//////////////////////////////////////////////////////////////////////////////
// LIST OF FUNCTIONS EXPORTED
//
// INBOUND =>
// ==========
// 1. IfsInitializeWrapper() :initializes a seed eg GUID for unique filenames.
// 2. IfsTerminateWrapper() :cleanup if necessary.
// *3. IfsCreateNewFileW() :given store prefix, return a HANDLE that can be
// used for storing data in that store.
// 4. IfsCacheInsertFile() :given an EA, insert filename in FH cache.
// 4. IfsMarshallHandle() :given an IFS handle, will return context that
// will aid in manifesting a new HANDLE in a
// different process.
// *5. IfsUnMarshallHandle() :given context from previous function, this will
// manifest a new HANDLE in current process.
//
// OUTBOUND =>
// ===========
// *1. IfsCacheCreateFile() :given an EA, get a file handle from the FH cache.
// if the file handle is not in FH cache, it will be
// created and inserted in FH cache.
// *2. IfsCreateFile() :given an EA, merely create a file handle -
// no FH cache insert/search.
// *3. IfsCreateFileRelative():given an EA, merely create a file handle -
// no FH cache insert/search - relative open
//
// *NOTE: Functions with an asterisk next to them return file HANDLES.
// It is expected that the caller will close these handles at an appropriate time !
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// INBOUND functions
//////////////////////////////////////////////////////////////////////////////
//
// This function sets up a seed GUID to aid generation of unique names !
//
BOOL __fastcall
IfsInitializeWrapper();
//
// This function cleans up any state setup in Init()
//
VOID __fastcall
IfsTerminateWrapper();
//
// Create a new IFS handle given a store prefix -
// The handle is opened for read/write. Caller should close
// handle after use. Closing the handle without committing the
// bytes (via NtQueryEa) will cause the bytes to be reused by IFS.
//
// NB: A fully qualified IFS filename is of the form:
// "\\??\\ExchangeIfs\\;E:\\<store-name>\\<root-name>\\<filename>"
// Typically, <store-name> is a constant for the machine,
// <root-name> is a function of a given MDB store and
// <filename> is a specific message in the store
//
// This functions expects the StorePrefix to be <store-name>\\<root-name>.
// The function will generate a unique <filename>
//
DWORD __fastcall
IfsCreateNewFileW(
IN LPWSTR StorePrefix,
IN DWORD FlagsOverride,
IN OUT PHANDLE phFile
);
#ifdef _USE_FHCACHE_
//
// Protocols should call this function to get an FIO_CONTEXT for
// an inbound message. This replaces IfsCreateNewFileW() as the
// preferred method of using the IFS/File Handle Cache.
//
FIO_CONTEXT*
IfsCreateInboundMessageFile(
IN LPWSTR StorePrefix,
IN DWORD FlagsOverride,
IN BOOL fScanForDots = TRUE
);
FIO_CONTEXT*
IfsCreateInboundMessageFileEx(
IN LPWSTR StorePrefix,
IN DWORD FlagsOverride,
IN BOOL fScanForDots = TRUE,
IN BOOL fStoredWithTerminatingDot = FALSE
);
//
// Given an FH cache FIO_CONTEXT and IFS EAs, insert file handle in
// FH cache using filename !
//
BOOL
IfsCacheInsertFile(
IN FIO_CONTEXT* pContext,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN BOOL fKeepReference
);
//
// Given an FH cache FIO_CONTEXT and IFS EAs, insert file handle in
// FH cache using filename !
// BINLIN - Caller of this function must ensure that EaBuffer has DotStuff state embedded!
// This can be achieved by calling IfsMarshallStoreEA() and marshall the returned EA
// buffer back to IIS, and use this EA buffer in IfsCacheInsertFileEx().
//
BOOL
IfsCacheInsertFileEx(
IN FIO_CONTEXT* pContext,
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN BOOL fKeepReference
);
BOOL IfsCacheWriteFile(
IN PFIO_CONTEXT pfioContext,
IN LPCVOID lpBuffer,
IN DWORD BytesToWrite,
IN FH_OVERLAPPED * lpo
);
BOOL IfsCacheReadFile(
IN PFIO_CONTEXT pfioContext,
IN LPCVOID lpBuffer,
IN DWORD BytesToRead,
IN FH_OVERLAPPED * lpo
);
DWORD IfsCacheGetFileSizeFromContext(
IN FIO_CONTEXT* pContext,
OUT DWORD* pcbFileSizeHigh
);
void IfsReleaseCacheContext( PFIO_CONTEXT pContext );
#endif
//
// Given an IFS handle, return context to be used by IfsUnMarshallHandle()
// in order to manifest a handle in another process !
//
// fUseEA should be used to decide whether marshalling is done via EAs
// or DuplicateHandle(). This function expects a buffer and buffer size.
// If the function return ERROR_SUCCESS, *pcbContext == size of data
// If the function returns ERROR_MORE_DATA, *pcbContext == size
// expected. Caller should allocate this size and make the request again !
//
DWORD
IfsMarshallHandle(
IN HANDLE hFile, // IFS file handle
IN BOOL fUseEA, // If TRUE, use EA to marshall
IN HANDLE hTargetProcess, // Handle to target process - optional
IN OUT PVOID pbContext, // ptr to buffer for context
IN OUT PDWORD pcbContext // IN - sizeof pbContext OUT - real size
);
#ifdef _USE_FHCACHE_
//
// This replaces IfsMarshallHandle() as the preferred way of marhalling
// handles. The FIO_CONTEXT contains the IFS handle.
//
DWORD
IfsMarshallHandleEx(
IN FIO_CONTEXT* pContext, // FH cache FIO_CONTEXT
IN BOOL fUseEA, // If TRUE, use EA to marshall
IN HANDLE hTargetProcess, // Handle to target process - optional
IN OUT PVOID pbContext, // ptr to buffer for context
IN OUT PDWORD pcbContext // IN - sizeof pbContext OUT - real size
);
#endif
//
// Give a context from IfsMarshallHandle(), return a handle usable in
// current process !
//
// Called in Store process only !
// The HANDLE this returns will refer to an EA that has the DOT Stuff State embedded !
//
DWORD
IfsUnMarshallHandle(
IN LPWSTR StorePrefix,
IN PVOID pbContext,
IN DWORD cbContext,
IN OUT PHANDLE phFile,
OUT PULONG pulDotStuffState = NULL
);
//////////////////////////////////////////////////////////////////////////////
// OUTBOUND functions
//////////////////////////////////////////////////////////////////////////////
#ifdef _USE_FHCACHE_
//
// Given an opaque EaBuffer and EaLength, return an FIO_CONTEXT from the
// File Handle Cache. Typically, used on outbound.
//
FIO_CONTEXT*
IfsCacheCreateFile(
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN BOOL fAsyncContext
);
//
// Given an opaque EaBuffer and EaLength, return an FIO_CONTEXT from the
// File Handle Cache. Typically, used on outbound.
// This replaces IfsCacheCreateFile() as the preferred way to do outbound.
// BINLIN - Caller of this function must ensure that EaBuffer has DotStuff state embedded.
// This can be achieved by calling IfsMarshallStoreEA() and marshall the returned EA
// buffer back to IIS, and use this EA buffer in IfsCacheInsertFileEx().
//
FIO_CONTEXT*
IfsCacheCreateFileEx(
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN BOOL fAsyncContext,
IN BOOL fWantItStuffed
);
#endif
//
// Create an IFS handle given an EaBuffer and EaLength -
// The handle is opened for read-only. EaBuffer can be freed
// after this call. Caller should close handle after use.
//
// NB: EaBuffer should have been obtained from a "trusted source"
// ie. ESE or IFS.
//
DWORD
IfsCreateFileRelative(
IN HANDLE hRoot,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN OUT PHANDLE phFile
);
//
// Create an IFS handle given an EaBuffer and EaLength -
// The handle is opened for read-only. EaBuffer can be freed
// after this call. Caller should close handle after use.
//
// NB: EaBuffer should have been obtained from a "trusted source"
// ie. ESE or IFS.
//
DWORD
IfsCreateFile(
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN OUT PHANDLE phFile
);
DWORD
IfsCreateFileEx(
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN OUT PHANDLE phFile,
IN BOOL fUniqueFileName,
IN DWORD desiredAccess
);
DWORD
IfsCreateFileEx2(
IN LPWSTR StorePrefix,
IN PVOID EaBuffer,
IN DWORD EaLength,
IN OUT PHANDLE phFile,
IN BOOL fUniqueFileName,
IN DWORD desiredAccess,
IN DWORD shareAccess,
IN DWORD createDisposition // see NT DDK
);
#ifdef _USE_FHCACHE_
//
// BINLIN - This function embeds the DotStuff state property into the real EA and
// return the ptr to the new EA buffer. Used only during outbound and before marshalling
// EA back to IIS for TransmitFile(), normally in the Store process.
// Here is the call sequence:
// 1) IIS request outbound message from Store
// 2) Store driver calls EcGetProp() on PR_DOTSTUFF_STATE to get DotStuff state property
// 3) Store driver calls EcGetFileHandleProp() to get real EA.
// 4) IF EA is returned, Store driver calls IfsMarshallStoreEA() and obtain a new EA buffer
// in pbMarshallEA, and marshall that to IIS.
// 5) IF HANDLE is returned, Store driver may call IfsMarshallHandle() to obtain EA.
// It then MUST CALL IfsMarshallStoreEA() to obtain new EA buffer pbMarshallEA.
// In general, if EA is obtained from Store or through IfsMarshallHandle(), the returned
// EA is not marshall-able until Store driver calls this function with DotStuff state to
// obtain a new EA buffer. Only marshall this new EA buffer to IIS, not the EA returned from Store!!!
//
// General rule of marshalling EA with DotStuff state - EA buffer marshall back and forth
// between IIS/Store always contain DotStuff state!
//
// NOTE:
// 1) Passing in 0 (or use default) for DotStuff state if one doesn't exist/available.
// 2) Caller must allocate memory for pbMarshallEA, and must be at least *pcbEA+sizeof(ulDotStuffState).
// 3) It's ok to pass in same buffer ptr for pbStoreEA and pbMarshallEA, as long as 2) is true.
//
DWORD
IfsMarshallStoreEA(
IN PVOID pbStoreEA, // ptr to buffer for EA returned from Store
IN OUT PDWORD pcbEA, // IN - sizeof pbStoreEA OUT - sizeof pbMarshallEA
OUT PVOID pbMarshallEA, // ptr to buffer for new EA ready for marshall
IN ULONG ulDotStuffState = 0 // Dotstuff state combined into pbMarshallEA with pbStoreEA
);
#endif
//////////////////////////////////////////////////////////////////////////////
// UTILITY functions - not meant to be used by clients of ifsuser.lib
//////////////////////////////////////////////////////////////////////////////
//
// Get filename from handle
//
DWORD
IfsGetFilenameFromHandle(
IN HANDLE hFile,
IN OUT LPSTR lpstrFilename
);
//
// Get filename from EA
//
VOID
IfsGetFilenameFromEaW(
IN PVOID EaBuffer,
IN OUT LPWSTR* ppwstrFilename
);
//
// Open a file with no EA
//
DWORD
IfsOpenFileNoEa(
IN LPWSTR lpwstrName,
IN OUT PHANDLE phFile
);
#ifdef NT_INCLUDED
//
// This is the function used by the I/O manager to check EA buffer
// validity. This can be used to debug EA_LIST_INCONSISTENT errors.
//
DWORD
CheckEaBufferValidity(
IN PFILE_FULL_EA_INFORMATION EaBuffer,
IN ULONG EaLength,
OUT PULONG ErrorOffset
);
#endif
#ifdef __cplusplus
}
#endif
#endif // _IFSUSER_H_