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.
 
 
 
 
 
 

531 lines
14 KiB

/*
* _ F S M E T A . H
*
* File system metadata routines
*
* Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
*/
#ifndef __FSMETA_H_
#define __FSMETA_H_
// STL helpers ---------------------------------------------------------------
//
// Use pragmas to disable the specific level 4 warnings
// that appear when we use the STL. One would hope our version of the
// STL compiles clean at level 4, but alas it doesn't....
#pragma warning(disable:4663) // C language, template<> syntax
#pragma warning(disable:4244) // return conversion, data loss
// Turn this warning off for good.
#pragma warning(disable:4786) // symbol truncated in debug info
// Put STL includes here
#include <list>
// Turn warnings back on
#pragma warning(default:4663) // C language, template<> syntax
#pragma warning(default:4244) // return conversion, data loss
// OLE and NT5 properties ----------------------------------------------------
//
#define OLEDBVER 0x200
#include <ole2.h>
#include <stgint.h>
#include <pbagex.h>
typedef HRESULT (__stdcall * STGOPENSTORAGEONHANDLE)(
IN HANDLE hStream,
IN DWORD grfMode,
IN void *reserved1,
IN void *reserved2,
IN REFIID riid,
OUT void **ppObjectOpen );
typedef HRESULT (__stdcall * STGCREATESTORAGEONHANDLE)(
IN HANDLE hStream,
IN DWORD grfMode,
IN DWORD stgfmt,
IN void *reserved1,
IN void *reserved2,
IN REFIID riid,
OUT void **ppObjectOpen );
extern STGOPENSTORAGEONHANDLE g_pfnStgOpenStorageOnHandle;
// reserved properties ------------------------------------------------------
//
// There are two conditions that make a property reserved.
//
// The first and foremost is that the property is not something that is stored
// in the resource's property container, but instead is calculated from file
// system information or DAV specific conditions (lock info, etc.)
//
// The second is that the property is not something that can be set via
// PROPPATCH calls. This distinction is needed when asking if a property is
// reserved.
//
enum {
// The properties in this section are all properties that are calculated
// from the filesystem or DAV specific information.
//
iana_rp_content_length,
iana_rp_creation_date,
iana_rp_displayname,
iana_rp_etag,
iana_rp_last_modified,
iana_rp_resourcetype,
iana_rp_lockdiscovery,
iana_rp_supportedlock,
iana_rp_ishidden,
iana_rp_iscollection,
sc_crp_get_reserved,
// The properties in this section are actually stored in the property
// container (via PUT) but are reserved for the purpose of PUT.
//
// IMPORTANT! "DAV:getcontenttype" must be the first non-get reserved
// property!
//
iana_rp_content_type = sc_crp_get_reserved,
iana_rp_content_encoding,
iana_rp_content_language,
// To be consistent with DAVEX, make the following property reserved
//
iana_rp_searchrequest,
sc_crp_set_reserved
};
typedef struct RP { DWORD dwCRC; LPCWSTR pwsz; } RP;
#define IanaItemCrc(_sz,_crc) { _crc, L"DAV:" L#_sz }
DEC_CONST RP sc_rp[sc_crp_set_reserved] = {
IanaItemCrc(getcontentlength, 0x25412A26),
IanaItemCrc(creationdate, 0xA8A9F240),
IanaItemCrc(displayname, 0xA399DB8D),
IanaItemCrc(getetag, 0x5E54D3B8),
IanaItemCrc(getlastmodified, 0x45D75CD4),
IanaItemCrc(resourcetype, 0x8155BECE),
IanaItemCrc(lockdiscovery, 0xC7ED2F96),
IanaItemCrc(supportedlock, 0x39B9A692),
IanaItemCrc(ishidden, 0xE31B1632),
IanaItemCrc(iscollection, 0xD3E3FF13),
IanaItemCrc(getcontenttype, 0xC28B9FED),
IanaItemCrc(getcontentencoding, 0x4B7C7220),
IanaItemCrc(getcontentlanguage, 0x5E9717C2),
IanaItemCrc(searchrequest, 0x5AC72D67),
};
// DAV Metadata --------------------------------------------------------------
//
#include <xmeta.h>
// The FS impl of DAV uses the NT5 property interfaces and IPropertyBag
// as its underlying property storage implementation. This mechanism uses
// strings and/or PROPVARIANTS to refer to properties and their values.
//
// Therefore the PROPFIND and PROPPATCH contexts are written with this in
// mind.
//
// CFSFind/CFSPatch ----------------------------------------------------------
//
class CFSProp;
class CFSFind : public CFindContext, public IPreloadNamespaces
{
ChainedStringBuffer<WCHAR> m_csb;
ULONG m_cProps;
ULONG m_cMaxProps;
auto_heap_ptr<LPCWSTR> m_rgwszProps;
LONG m_ip_getcontenttype;
// non-implemented operators
//
CFSFind( const CFSFind& );
CFSFind& operator=( const CFSFind& );
public:
virtual ~CFSFind() {}
CFSFind()
: m_cProps(0),
m_cMaxProps(0),
m_ip_getcontenttype(-1)
{
}
// When the parser finds an item that the client wants returned,
// the item is added to the context via the following set context
// methods. Each add is qualified by the resource on which the
// request is made. fExcludeProp is used for full-fidelity special
// cases in the Exchange implementation only.
//
virtual SCODE ScAddProp(LPCWSTR pwszPath, LPCWSTR pwszProp, BOOL fExcludeProp);
// The ScFind() method is used to invoke the context onto a given
// resources property object.
//
SCODE ScFind (CXMLEmitter& msr, IMethUtil * pmu, CFSProp& fpt);
// Add an error to the response that is based on the context.
//
SCODE ScErrorAllProps (CXMLEmitter& msr,
IMethUtil * pmu,
LPCWSTR pwszPath,
BOOL fCollection,
CVRoot* pcvrTranslation,
SCODE scErr)
{
// Add an item to the msr that says this entire
// file was not accessible
//
return ScAddMulti (msr,
pmu,
pwszPath,
NULL,
HscFromHresult(scErr),
fCollection,
pcvrTranslation);
}
// IPreloadNamespaces
//
SCODE ScLoadNamespaces(CXMLEmitter * pmsr);
};
class CFSPatch : public CPatchContext, public IPreloadNamespaces
{
class CFSPropContext : public CPropContext
{
PROPVARIANT* m_pvar;
BOOL m_fHasValue;
// non-implemented operators
//
CFSPropContext( const CFSPropContext& );
CFSPropContext& operator=( const CFSPropContext& );
public:
CFSPropContext(PROPVARIANT* pvar)
: m_pvar(pvar),
m_fHasValue(FALSE)
{
Assert (pvar != NULL);
}
virtual ~CFSPropContext() {}
virtual SCODE ScSetType(LPCWSTR pwszType)
{
return ScVariantTypeFromString (pwszType, m_pvar->vt);
}
virtual SCODE ScSetValue(LPCWSTR pwszValue, UINT cmvValues)
{
// At this time, HTTPEXT does not support multivalued
// properties.
//
Assert (0 == cmvValues);
// If no type was specified, we default to a string
//
m_fHasValue = TRUE;
if (m_pvar->vt == VT_EMPTY)
m_pvar->vt = VT_LPWSTR;
return ScVariantValueFromString (*m_pvar, pwszValue);
}
virtual SCODE ScComplete(BOOL fEmpty)
{
Assert (m_fHasValue);
return m_fHasValue ? S_OK : E_DAV_XML_PARSE_ERROR;
}
// At this time, HTTPEXT does not support multivalued
// properties.
//
virtual BOOL FMultiValued() { return FALSE; }
};
// PATCH_SET items
//
ChainedStringBuffer<WCHAR> m_csb;
ULONG m_cSetProps;
ULONG m_cMaxSetProps;
auto_heap_ptr<LPCWSTR> m_rgwszSetProps;
auto_heap_ptr<PROPVARIANT> m_rgvSetProps;
// Failed Propserties including reserverd properties
//
CStatusCache m_csn;
// PATCH_DELETE items
//
ULONG m_cDeleteProps;
ULONG m_cMaxDeleteProps;
auto_heap_ptr<LPCWSTR> m_rgwszDeleteProps;
// non-implemented operators
//
CFSPatch( const CFSPatch& );
CFSPatch& operator=( const CFSPatch& );
public:
virtual ~CFSPatch();
CFSPatch()
: m_cSetProps(0),
m_cMaxSetProps(0),
m_cDeleteProps(0),
m_cMaxDeleteProps(0)
{
}
SCODE ScInit() { return m_csn.ScInit(); }
// When the parser finds an item that the client wants operated on,
// the item is added to the context via the following set context
// methods. Each request is qualified by the resource on which the
// request is made.
//
virtual SCODE ScDeleteProp(LPCWSTR pwszPath,
LPCWSTR pwszProp);
virtual SCODE ScSetProp(LPCWSTR pwszPath,
LPCWSTR pwszProp,
auto_ref_ptr<CPropContext>& pPropCtx);
// The ScPatch() method is used to invoke the context onto a given
// resources property object.
//
SCODE ScPatch (CXMLEmitter& msr, IMethUtil * pmu, CFSProp& fpt);
// IPreloadNamespaces
//
SCODE ScLoadNamespaces(CXMLEmitter * pmsr);
};
// CFSProp -------------------------------------------------------------------
//
#include "_voltype.h"
class CFSProp
{
IMethUtil* m_pmu;
LPCWSTR m_pwszURI;
LPCWSTR m_pwszPath;
CVRoot* m_pcvrTranslation;
CResourceInfo& m_cri;
auto_com_ptr<IPropertyBagEx>& m_pbag;
BOOL FInvalidPbag() const { return (m_pbag.get() == NULL); }
// Volume type of the drive on which m_pwszPath resides
//
mutable VOLTYPE m_voltype;
BOOL FIsVolumeNTFS() const
{
// If we don't already know it, figure out the volume type
// for the volume on which our path resides.
//
if (VOLTYPE_UNKNOWN == m_voltype)
m_voltype = VolumeType(m_pwszPath, m_pmu->HitUser());
// Return whether that volume is NTFS.
//
Assert(m_voltype != VOLTYPE_UNKNOWN);
return VOLTYPE_NTFS == m_voltype;
}
// non-implemented operators
//
CFSProp( const CFSProp& );
CFSProp& operator=( const CFSProp& );
enum { PROP_CHUNK_SIZE = 16 };
SCODE ScGetPropsInternal (ULONG cProps,
LPCWSTR* rgwszPropNames,
PROPVARIANT* rgvar,
LONG ip_getcontenttype);
public:
CFSProp(IMethUtil* pmu,
auto_com_ptr<IPropertyBagEx>& pbag,
LPCWSTR pwszUri,
LPCWSTR pwszPath,
CVRoot* pcvr,
CResourceInfo& cri)
: m_pmu(pmu),
m_pwszURI(pwszUri),
m_pwszPath(pwszPath),
m_pcvrTranslation(pcvr),
m_cri(cri),
m_pbag(pbag),
m_voltype(VOLTYPE_UNKNOWN)
{
}
LPCWSTR PwszPath() const { return m_pwszPath; }
CVRoot* PcvrTranslation() const { return m_pcvrTranslation; }
BOOL FCollection() const
{
if (m_cri.FLoaded())
return m_cri.FCollection();
else
return FALSE;
}
// Reserved Properties
//
typedef enum { RESERVED_GET, RESERVED_SET } RESERVED_TYPE;
static BOOL FReservedProperty (LPCWSTR pwszProp, RESERVED_TYPE rt, UINT* prp);
SCODE ScGetReservedProp (CXMLEmitter& xml,
CEmitterNode& en,
UINT irp,
BOOL fValues = TRUE);
// PROPFIND context access
//
SCODE ScGetAllProps (CXMLEmitter&, CEmitterNode&, BOOL fValues);
SCODE ScGetSpecificProps (CXMLEmitter&,
CEmitterNode&,
ULONG cProps,
LPCWSTR* rgwszProps,
LONG ip_gcontenttype);
// PROPPATCH context access
//
SCODE ScSetProps (CStatusCache & csn,
ULONG cProps,
LPCWSTR* rgwszProps,
PROPVARIANT* rgvProps);
SCODE ScDeleteProps (CStatusCache & csn,
ULONG cProps,
LPCWSTR* rgwszProps);
SCODE ScPersist();
// Non-context access
//
SCODE ScSetStringProp (LPCWSTR pwszProp, LPCWSTR pwszValue)
{
PROPVARIANT var = {0};
SCODE sc = S_OK;
var.vt = VT_LPWSTR;
var.pwszVal = const_cast<LPWSTR>(pwszValue);
Assert (!FInvalidPbag());
sc = m_pbag->WriteMultiple (1, &pwszProp, &var);
if (FAILED(sc))
{
// This is the common path for when we are trying to access
// something over an SMB, but the host cannot support the
// request (it is not an NT5 NTFS machine).
//
if ((sc == STG_E_INVALIDNAME) || !FIsVolumeNTFS())
sc = E_DAV_SMB_PROPERTY_ERROR;
}
return sc;
}
};
// Support functions ---------------------------------------------------------
//
SCODE ScFindFileProps (IMethUtil* pmu,
CFSFind& cfc,
CXMLEmitter& msr,
LPCWSTR pwszUri,
LPCWSTR pwszPath,
CVRoot* pcvrTranslation,
CResourceInfo& cri,
BOOL fEmbedErrorsInResponse);
SCODE ScFindFilePropsDeep (IMethUtil* pmu,
CFSFind& cfc,
CXMLEmitter& msr,
LPCWSTR pwszUri,
LPCWSTR pwszPath,
CVRoot* pcvrTranslation,
LONG lDepth);
SCODE ScSetContentProperties (IMethUtil * pmu, LPCWSTR pwszPath,
HANDLE hFile = INVALID_HANDLE_VALUE);
SCODE ScCopyProps (IMethUtil* pmu,
LPCWSTR pwszSrc,
LPCWSTR pwszDst,
BOOL fCollection,
HANDLE hSource = INVALID_HANDLE_VALUE,
HANDLE hfDest = INVALID_HANDLE_VALUE);
// ScGetPropertyBag ----------------------------------------------------------
//
// Helper function used to get IPropertyBagEx interface
//
SCODE ScGetPropertyBag (LPCWSTR pwszPath,
DWORD dwAccessDesired,
IPropertyBagEx** ppbe,
BOOL fCollection,
HANDLE hLockFile = INVALID_HANDLE_VALUE);
inline BOOL FGetDepth (IMethUtil * pmu, LONG * plDepth)
{
LONG lDepth = pmu->LDepth (DEPTH_INFINITY);
// "Depth" header, if appears, can only be '0', '1' or 'infinity',
// all other values are treated as error
//
switch (lDepth)
{
case DEPTH_ZERO:
case DEPTH_ONE:
case DEPTH_ONE_NOROOT:
case DEPTH_INFINITY:
*plDepth = lDepth;
break;
default:
return FALSE;
}
return TRUE;
}
// safe_statpropbag -------------------------------------------------------------
//
#pragma pack(8)
class safe_statpropbag
{
// IMPORTANT: Do not add any other members to this class
// other than the STATPROP that is to be protected.
//
STATPROPBAG sp;
// non-implemented
//
safe_statpropbag(const safe_statpropbag& b);
safe_statpropbag& operator=(const safe_statpropbag& b);
public:
explicit safe_statpropbag()
{
memset (&sp, 0, sizeof(safe_statpropbag));
}
~safe_statpropbag()
{
CoTaskMemFree (sp.lpwstrName);
}
// ACCESSORS
//
STATPROPBAG* load() { return &sp; }
STATPROPBAG get() { return sp; }
};
#pragma pack()
#endif // __FSMETA_H_