📄 davxml.h
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: davxml.h
Abstract: Parses XML in POST data for DAV verbs
--*/
#include "httpd.h"
//
// Base class that other parsers inherit from
//
// By default any character data sent in an XML tag will be discarded. Set
// this flag for any properties that character data needs to be saved for.
#define DAV_STATE_SAVE_CHARACTERS 0x1000
#define DAV_STATE_UNINITAILIZED 0
#define DAV_STATE_UNKNOWN 1
#define DAV_STATE_UNRECOGNIZED_TAG 2
typedef enum {
NAMESPACE_DAV,
NAMESPACE_MS,
} DAV_NAMESPACE;
class CDavParse : public SVSSAXContentHandler {
protected:
DWORD m_State;
DWORD m_PreviousState;
int m_iUnknownDepth; // Number of unknown tags on "stack"
CWebDav *m_pWebDav;
SVSSimpleBuffer m_Chars;
public:
CDavParse(CWebDav *pWebDav) {
m_pWebDav = pWebDav;
m_PreviousState = m_State = DAV_STATE_UNINITAILIZED;
m_iUnknownDepth = 0;
}
~CDavParse() { ; }
// Verify data sent to us is as it should be
BOOL PrepareNonEmptyBuf(void);
BOOL VerifyNS(DAV_NAMESPACE ns, const WCHAR *szNamespace, DWORD ccNamespace);
BOOL VerifyRequiredTag(const CHAR *szTokenExpected, DWORD ccExpected, const CHAR *szLocalName, DWORD ccLocalName);
// SAX implementation. Leave startElement and endElement to particular search class.
virtual HRESULT STDMETHODCALLTYPE characters(const wchar_t *pwchChars, int cchChars) {
if (! (m_State & DAV_STATE_SAVE_CHARACTERS))
return S_OK;
if (m_Chars.Append((PSTR) pwchChars, cchChars*sizeof(WCHAR)))
return S_OK;
return E_FAIL;
}
// When we get a tag we don't know about, save old state temporarily.
//
void SetUnknownTag(void) {
if (m_State != DAV_STATE_UNRECOGNIZED_TAG) {
DEBUGCHK(m_iUnknownDepth == 0);
m_iUnknownDepth++;
m_PreviousState = m_State;
m_State = DAV_STATE_UNRECOGNIZED_TAG;
}
else {
DEBUGCHK(m_iUnknownDepth);
m_iUnknownDepth++;
}
}
void RestoreUnknownTagState(void) {
DEBUGCHK(m_State == DAV_STATE_UNRECOGNIZED_TAG);
m_iUnknownDepth--;
if (m_iUnknownDepth == 0)
m_State = m_PreviousState;
}
};
//
// PROPFIND
//
// PROPFIND has the form:
// <propfind>
// <propname/>|<allprop/>|<prop>
// <propname> returns only property names (not values) for source URL
// <allprop> returns all property names and values for source URL
// <prop> is theoretically free-form XML specifying which properties to receive.
// CE supports only the fixed tags such as <getcontentlength> and <getcontentlength>.
// PropFind states
#define PROPFIND_STATE_PROPFIND 10
#define PROPFIND_STATE_PROP 11
#define PROPFIND_STATE_ALLPROP 12
#define PROPFIND_STATE_PROPNAME 13
#define PROPFIND_STATE_CONTENT_LEN 14
#define PROPFIND_STATE_DISPLAY_NAME 15
#define PROPFIND_STATE_CREATION_DATE 16
#define PROPFIND_STATE_GET_ETAG 17
#define PROPFIND_STATE_LAST_MODIFIED 18
#define PROPFIND_STATE_RESOURCE_TYPE 19
#define PROPFIND_STATE_IS_HIDDEN 20
#define PROPFIND_STATE_IS_COLLECTION 21
#define PROPFIND_STATE_SUPPORTED_LOCK 22
#define PROPFIND_STATE_LOCK_DISCOVERY 23
#define PROPFIND_STATE_CONTENT_TYPE 24
class CPropFindParse : public CDavParse {
DWORD m_dwDavProperties; // subset of properties to send, mask of DAV_PROP_xxx flags.
public:
CPropFindParse(CWebDav *pWebDav) : CDavParse(pWebDav) {
m_dwDavProperties = 0;
}
~CPropFindParse(void) { ; }
// implemented SAX functions.
virtual HRESULT STDMETHODCALLTYPE startElement(const wchar_t * pwchNamespaceUri, int cchNamespaceUri, const wchar_t * pwchLocalName,
int cchLocalName, const wchar_t * pwchQName, int cchQName, ISAXAttributes * pAttributes);
virtual HRESULT STDMETHODCALLTYPE endElement(const wchar_t *pwchNamespaceUri, int cchNamespaceUri, const wchar_t *pwchLocalName,
int cchLocalName, const wchar_t *pwchQName, int cchQName);
};
//
// PROPPATCH
//
// PROPPATCH has the form:
// <propertyupdate>
// <set|remove> // one or more such elements.
// <prop> ... </prop>
// <prop> tag is theoretically free-form XML specifying properties to set,
// though CE has a limited set of what will be accepted.
// PropPatch states
#define PROPPATCH_STATE_PROPERTYUPDATE 10
#define PROPPATCH_STATE_SET 11
#define PROPPATCH_STATE_REMOVE 12
#define PROPPATCH_STATE_PROP 13
#define PROPPATCH_STATE_WIN32_LAST_ACCESS 14
#define PROPPATCH_STATE_WIN32_LAST_MODIFIED 15
#define PROPPATCH_STATE_WIN32_CREATION_TIME 16
#define PROPPATCH_STATE_WIN32_FILE_ATTRIBS (DAV_STATE_SAVE_CHARACTERS+0)
class CPropPatchParse : public CDavParse {
public:
CPropPatchParse(CWebDav *pWebDav) : CDavParse(pWebDav) { ; }
~CPropPatchParse(void) { ; }
// implemented SAX functions.
virtual HRESULT STDMETHODCALLTYPE startElement(const wchar_t * pwchNamespaceUri, int cchNamespaceUri, const wchar_t * pwchLocalName,
int cchLocalName, const wchar_t * pwchQName, int cchQName, ISAXAttributes * pAttributes);
virtual HRESULT STDMETHODCALLTYPE endElement(const wchar_t *pwchNamespaceUri, int cchNamespaceUri, const wchar_t *pwchLocalName,
int cchLocalName, const wchar_t *pwchQName, int cchQName);
};
//
// LOCK
//
// LOCK has the form:
// <lockinfo>
// <lockscope>(<exclusive/>|<shared/>)</lockscope>
// <locktype><write/></locktype>
// <owner><href></owner>
#define LOCK_STATE_LOCKINFO 10
#define LOCK_STATE_LOCKSCOPE 11
#define LOCK_STATE_EXCLUSIVE 12
#define LOCK_STATE_SHARED 13
#define LOCK_STATE_LOCKTYPE 14
#define LOCK_STATE_WRITE 15
#define LOCK_STATE_OWNER (DAV_STATE_SAVE_CHARACTERS+0)
// CNameSpaceMap contains mappings between namespace name and the prefix. However
// it's possible for a namespace prefix to be overriden based on scoping rules of XML
// (i.e <a xmlns:d="Fo"><b xmlns:d="Fo2">...). So if we get multiple name spaces of
// same name put additional mappings under m_pChild.
class CNameSpaceMap {
private:
// make these private as this class is only initialized through small block allocator anyway...
CNameSpaceMap() {; }
~CNameSpaceMap() { ; }
public:
WCHAR *m_szPrefix;
WCHAR *m_szURI;
CNameSpaceMap *m_pNext; // sibling in linked list
CNameSpaceMap *m_pChild;
BOOL Init(const WCHAR *szPrefix, const WCHAR *szURI) {
m_pChild = m_pNext = NULL;
m_szPrefix = m_szURI = NULL;
if (szPrefix) {
if (NULL == (m_szPrefix = MySzDupW(szPrefix)))
return FALSE;
}
if (NULL == (m_szURI = MySzDupW(szURI)))
return FALSE;
return TRUE;
}
void DeInit(void) {
MyFree(m_szPrefix);
MyFree(m_szURI);
}
};
class CLockParse : public CDavParse {
private:
friend class CWebDavFileLockManager;
// DWORD m_dwLockAccess; // CreateFile for DavLock is always opened with (GENERIC_READ | GENERIC_WRITE).
DAV_LOCK_SHARE_MODE m_lockShareMode;
SVSXMLWriter m_OwnerXML;
PSTR m_szLockOwner;
// keep a mapping between name space prefixes and URI's for <owner> tag printout.
BOOL m_fReadNameSpaceMap; // Do we have to do NS processing? We don't once we've handled <owner>
CNameSpaceMap *m_NSList; // List of name spaces.
FixedMemDescr *m_NSDescr; // Memory for queue
void SetSharedLock(void) { m_lockShareMode = DAV_LOCK_SHARED; }
void SetExclusiveLock(void) { m_lockShareMode = DAV_LOCK_EXCLUSIVE; }
BOOL SetLockOwner(void) {
MyFreeNZ(m_szLockOwner);
if (m_OwnerXML.GetNumChars() == 0) {
// If the owner is empty, then store an empty string.
if (NULL == (m_szLockOwner = MySzDupA(cszEmpty)))
return FALSE;
return TRUE;
}
if (FAILED(m_OwnerXML.characters(L"\0",1)))
return FALSE;
if (NULL == (m_szLockOwner = m_OwnerXML.ConvertOutput(CP_ACP)))
return FALSE;
return TRUE;
}
// LOCK accessors, when parsing XML
// SetWriteLockType does nothing for now, because we only support write locks.
void SetWriteLockType(void) { ;}
public:
CLockParse(CWebDav *pWebDav) : CDavParse(pWebDav) {
m_szLockOwner = NULL;
m_lockShareMode = DAV_LOCK_UNKNOWN;
m_fReadNameSpaceMap = TRUE;
m_NSDescr = svsutil_AllocFixedMemDescr(sizeof(CNameSpaceMap),10);
m_NSList = NULL;
}
~CLockParse(void) {
MyFreeNZ(m_szLockOwner);
while (m_NSList) {
// For each item in the list
CNameSpaceMap *pNext = m_NSList->m_pNext;
CNameSpaceMap *pChild = m_NSList;
while (pChild) {
// For each child element.
CNameSpaceMap *pNextChild = pChild->m_pChild;
pChild->DeInit();
svsutil_FreeFixed(pChild,m_NSDescr);
pChild = pNextChild;
}
m_NSList = pNext;
}
svsutil_ReleaseFixedEmpty(m_NSDescr);
}
// implemented SAX functions.
virtual HRESULT STDMETHODCALLTYPE startElement(const wchar_t * pwchNamespaceUri, int cchNamespaceUri, const wchar_t * pwchLocalName,
int cchLocalName, const wchar_t * pwchQName, int cchQName, ISAXAttributes * pAttributes);
virtual HRESULT STDMETHODCALLTYPE endElement(const wchar_t *pwchNamespaceUri, int cchNamespaceUri, const wchar_t *pwchLocalName,
int cchLocalName, const wchar_t *pwchQName, int cchQName);
virtual HRESULT STDMETHODCALLTYPE characters(const wchar_t *pwchChars, int cchChars) {
// special handeling for LOCK characters. Currently only data we care
// about lives inside <owner> tag, but because this could be XML we need to
// use
if (m_State != LOCK_STATE_OWNER)
return S_OK;
return m_OwnerXML.characters(pwchChars,cchChars);
}
virtual HRESULT STDMETHODCALLTYPE processingInstruction(const wchar_t __RPC_FAR *pwchTarget,int cchTarget,
const wchar_t __RPC_FAR *pwchData, int cchData)
{
if (m_State != LOCK_STATE_OWNER)
return S_OK;
return m_OwnerXML.processingInstruction(pwchTarget,cchTarget,pwchData,cchData);
}
// Spit out XML tags into a file stream.
BOOL WriteXMLTagToBuffer(const wchar_t * pwchNamespaceUri, int cchNamespaceUri, const wchar_t * pwchLocalName,
int cchLocalName, const wchar_t * pwchQName, int cchQName, ISAXAttributes * pAttributes, BOOL fIsStartTag);
// Keep track of Prefix Mappings because we may need to spit them out again
// for the owner tag...
virtual HRESULT STDMETHODCALLTYPE startPrefixMapping(
/* [in] */ const wchar_t __RPC_FAR *pwchPrefix,
/* [in] */ int cchPrefix,
/* [in] */ const wchar_t __RPC_FAR *pwchUri,
/* [in] */ int cchUri);
virtual HRESULT STDMETHODCALLTYPE endPrefixMapping(
/* [in] */ const wchar_t __RPC_FAR *pwchPrefix,
/* [in] */ int cchPrefix);
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -