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.
730 lines
32 KiB
730 lines
32 KiB
// --------------------------------------------------------------------------------
|
|
// Ixphttpm.h
|
|
// Copyright (c)1998 Microsoft Corporation, All Rights Reserved
|
|
// Greg Friedman
|
|
// --------------------------------------------------------------------------------
|
|
#ifndef __IXPHTTPM_H
|
|
#define __IXPHTTPM_H
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Includes
|
|
// --------------------------------------------------------------------------------
|
|
#include <stddef.h> // for offsetof
|
|
|
|
#include "wininet.h"
|
|
#include "propfind.h"
|
|
#include "xmlparser.h"
|
|
#include "davparse.h"
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// constants
|
|
// --------------------------------------------------------------------------------
|
|
#define ELE_STACK_CAPACITY 7
|
|
#define HTTPMAIL_BUFSIZE 4048
|
|
#define PCDATA_BUFSIZE 1024
|
|
|
|
// optional headers added to http requests
|
|
#define RH_NOROOT 0x00000001
|
|
#define RH_ALLOWRENAME 0x00000002
|
|
#define RH_TRANSLATEFALSE 0x00000004
|
|
#define RH_TRANSLATETRUE 0x00000008
|
|
#define RH_XMLCONTENTTYPE 0x00000010
|
|
#define RH_MESSAGECONTENTTYPE 0x00000020
|
|
#define RH_SMTPMESSAGECONTENTTYPE 0x00000040
|
|
#define RH_BRIEF 0x00000080
|
|
#define RH_SAVEINSENTTRUE 0x00000100
|
|
#define RH_SAVEINSENTFALSE 0x00000200
|
|
#define RH_ROOTTIMESTAMP 0x00000400
|
|
#define RH_FOLDERTIMESTAMP 0x00000800
|
|
#define RH_ADDCHARSET 0x00001000
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Forward declarations
|
|
// --------------------------------------------------------------------------------
|
|
class CHTTPMailTransport;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// root props
|
|
// --------------------------------------------------------------------------------
|
|
typedef struct tagROOTPROPS
|
|
{
|
|
LPSTR pszAdbar;
|
|
LPSTR pszContacts;
|
|
LPSTR pszInbox;
|
|
LPSTR pszOutbox;
|
|
LPSTR pszSendMsg;
|
|
LPSTR pszSentItems;
|
|
LPSTR pszDeletedItems;
|
|
LPSTR pszDrafts;
|
|
LPSTR pszMsgFolderRoot;
|
|
LPSTR pszSig;
|
|
DWORD dwMaxPollingInterval;
|
|
} ROOTPROPS, *LPROOTPROPS;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Schemas used for XML parsing
|
|
// --------------------------------------------------------------------------------
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XPCOLUMNDATATYPE
|
|
// --------------------------------------------------------------------------------
|
|
typedef enum tagXPCOLUMNDATATYPE
|
|
{
|
|
XPCDT_STRA,
|
|
XPCDT_DWORD,
|
|
XPCDT_BOOL,
|
|
XPCDT_IXPHRESULT,
|
|
XPCDT_HTTPSPECIALFOLDER,
|
|
XPCDT_HTTPCONTACTTYPE,
|
|
XPCDT_LASTTYPE
|
|
} XPCOLUMNDATATYPE;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XPCOLUMN FLAGS
|
|
// --------------------------------------------------------------------------------
|
|
#define XPCF_PFREQUEST 0x00000001 // include in propfind request
|
|
#define XPCF_MSVALIDMSRESPONSECHILD 0x00000002 // during parse - validate that the ele stack is correct for a child of a <response> in a <multistatus> response
|
|
#define XPCF_MSVALIDPROP 0x00000004 // during parse - validate that the stack is correct for a propvalue in an ms response
|
|
#define XPCF_DONTSETFLAG 0x00000008 // don't set the found flag when parsing
|
|
|
|
#define XPFC_PROPFINDPROP (XPCF_PFREQUEST | XPCF_MSVALIDPROP)
|
|
#define XPCF_PROPFINDHREF (XPCF_MSVALIDMSRESPONSECHILD | XPCF_DONTSETFLAG)
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XPCOLUMN
|
|
// --------------------------------------------------------------------------------
|
|
typedef struct tagXPCOLUMN
|
|
{
|
|
HMELE ele;
|
|
DWORD dwFlags;
|
|
XPCOLUMNDATATYPE cdt;
|
|
DWORD offset;
|
|
} XPCOLUMN, *LPXPCOLUMN;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_BEGIN_SCHEMA
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_BEGIN_SCHEMA(opName) \
|
|
static const XPCOLUMN c_rg##opName##Schema[] = {
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_SCHEMA_COL
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_SCHEMA_COL(ele, dwFlags, cdt, tyStruct, fieldName ) \
|
|
{ ele, dwFlags, cdt, offsetof(tyStruct, fieldName) },
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_END_SCHEMA
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_END_SCHEMA \
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_FREE_STRUCT
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_FREE_STRUCT(opName, target, flags) \
|
|
_FreeStruct(c_rg##opName##Schema, ARRAYSIZE(c_rg##opName##Schema), target, flags)
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_BIND_TO_STRUCT
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_BIND_TO_STRUCT(opName, pwcText, ulLen, target, wasBound) \
|
|
_BindToStruct(pwcText, ulLen, c_rg##opName##Schema, ARRAYSIZE(c_rg##opName##Schema), target, wasBound)
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XP_CREATE_PROPFIND_REQUEST
|
|
// --------------------------------------------------------------------------------
|
|
#define XP_CREATE_PROPFIND_REQUEST(opName, pRequest) \
|
|
HrAddPropFindSchemaProps(pRequest, c_rg##opName##Schema, ARRAYSIZE(c_rg##opName##Schema))
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// State Machine Funcs
|
|
// --------------------------------------------------------------------------------
|
|
typedef HRESULT (CHTTPMailTransport::*PFNHTTPMAILOPFUNC)(void);
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// XML Parsing Funcs
|
|
// --------------------------------------------------------------------------------
|
|
typedef HRESULT (CHTTPMailTransport::*PFNCREATEELEMENT)(CXMLNamespace *pBaseNamespace, const WCHAR *pwcText, ULONG ulLen, ULONG ulNamespaceLen, BOOL fTerminal);
|
|
typedef HRESULT (CHTTPMailTransport::*PFNHANDLETEXT)(const WCHAR *pwcText, ULONG ulLen);
|
|
typedef HRESULT (CHTTPMailTransport::*PFNENDCHILDREN)(void);
|
|
|
|
typedef struct tagXMLPARSEFUNCS
|
|
{
|
|
PFNCREATEELEMENT pfnCreateElement;
|
|
PFNHANDLETEXT pfnHandleText;
|
|
PFNENDCHILDREN pfnEndChildren;
|
|
} XMLPARSEFUNCS, *LPXMLPARSEFUNCS;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Utility functions
|
|
// --------------------------------------------------------------------------------
|
|
HRESULT HrParseHTTPStatus(LPSTR pszStatusStr, DWORD *pdwStatus);
|
|
HRESULT HrAddPropFindProps(IPropFindRequest *pRequest, const HMELE *rgEle, DWORD cEle);
|
|
HRESULT HrAddPropFindSchemaProps(IPropFindRequest *pRequest, const XPCOLUMN *prgCols, DWORD cCols);
|
|
HRESULT _HrGenerateRfc821Stream(LPCSTR pszFrom, LPHTTPTARGETLIST pTargets, IStream **ppRfc821Stream);
|
|
HRESULT HrGeneratePostContactXML(LPHTTPCONTACTINFO pciInfo, LPVOID *ppvXML, DWORD *pdwLen);
|
|
HRESULT HrCreatePatchContactRequest(LPHTTPCONTACTINFO pciInfo, IPropPatchRequest **ppRequest);
|
|
HRESULT HrGenerateSimpleBatchXML(LPCSTR pszRootName, LPHTTPTARGETLIST pTargets, LPVOID *ppvXML, DWORD *pdwLen);
|
|
HRESULT HrGenerateMultiDestBatchXML(LPCSTR pszRootName, LPHTTPTARGETLIST pTargets, LPHTTPTARGETLIST pDestinations, LPVOID *ppvXML, DWORD *pdwLen);
|
|
HRESULT HrCopyStringList(LPCSTR *rgszInList, LPCSTR **prgszOutList);
|
|
void FreeStringList(LPCSTR *rgszInList);
|
|
|
|
typedef struct tagHTTPQUEUEDOP
|
|
{
|
|
HTTPMAILCOMMAND command;
|
|
|
|
const PFNHTTPMAILOPFUNC *pfnState;
|
|
int cState;
|
|
|
|
LPSTR pszUrl;
|
|
LPSTR pszDestination;
|
|
LPCSTR pszContentType;
|
|
LPVOID pvData;
|
|
ULONG cbDataLen;
|
|
DWORD dwContext;
|
|
DWORD dwDepth;
|
|
DWORD dwRHFlags;
|
|
MEMBERINFOFLAGS dwMIFlags;
|
|
HTTPMAILPROPTYPE tyProp;
|
|
BOOL fBatch;
|
|
LPCSTR *rgszAcceptTypes;
|
|
IPropFindRequest *pPropFindRequest;
|
|
IPropPatchRequest *pPropPatchRequest;
|
|
|
|
IStream *pHeaderStream;
|
|
IStream *pBodyStream;
|
|
|
|
const XMLPARSEFUNCS *pParseFuncs;
|
|
|
|
struct tagHTTPQUEUEDOP *pNext;
|
|
|
|
// Used with Folders PropFind and Inbox PropFind.
|
|
LPSTR pszFolderTimeStamp;
|
|
|
|
// Used only with Folders PropFind.
|
|
LPSTR pszRootTimeStamp;
|
|
|
|
} HTTPQUEUEDOP, *LPHTTPQUEUEDOP;
|
|
|
|
typedef struct tagPCDATABUFFER
|
|
{
|
|
WCHAR *pwcText;
|
|
ULONG ulLen;
|
|
ULONG ulCapacity;
|
|
} PCDATABUFFER, *LPPCDATABUFFER;
|
|
|
|
typedef struct tagHMELESTACK
|
|
{
|
|
HMELE ele;
|
|
CXMLNamespace *pBaseNamespace;
|
|
BOOL fBeganChildren;
|
|
LPPCDATABUFFER pTextBuffer;
|
|
} HMELESTACK, *LPHMELESTACK;
|
|
|
|
|
|
typedef struct tagHTTPMAILOPERATION
|
|
{
|
|
const PFNHTTPMAILOPFUNC *pfnState;
|
|
int iState;
|
|
int cState;
|
|
|
|
BOOL fLoggedResponse;
|
|
|
|
LPSTR pszUrl;
|
|
LPSTR pszDestination;
|
|
LPCSTR pszContentType;
|
|
LPVOID pvData;
|
|
ULONG cbDataLen;
|
|
DWORD dwContext;
|
|
|
|
DWORD dwHttpStatus; // http response status
|
|
|
|
LPCSTR *rgszAcceptTypes;
|
|
|
|
HINTERNET hRequest;
|
|
BOOL fAborted;
|
|
DWORD dwDepth;
|
|
DWORD dwRHFlags;
|
|
MEMBERINFOFLAGS dwMIFlags;
|
|
HTTPMAILPROPTYPE tyProp;
|
|
BOOL fBatch;
|
|
IPropFindRequest *pPropFindRequest;
|
|
IPropPatchRequest *pPropPatchRequest;
|
|
LPPCDATABUFFER pTextBuffer;
|
|
|
|
IStream *pHeaderStream;
|
|
IStream *pBodyStream;
|
|
|
|
// xml parsing
|
|
const XMLPARSEFUNCS *pParseFuncs;
|
|
CXMLNamespace *pTopNamespace;
|
|
DWORD dwStackDepth;
|
|
HMELESTACK rgEleStack[ELE_STACK_CAPACITY];
|
|
|
|
// PropFind Parsing
|
|
BOOL fFoundStatus;
|
|
DWORD dwStatus;
|
|
DWORD dwPropFlags;
|
|
|
|
// response
|
|
HTTPMAILRESPONSE rResponse;
|
|
|
|
// Used with Folders PropFind and Inbox PropFind.
|
|
LPSTR pszFolderTimeStamp;
|
|
|
|
// Used only with Folders PropFind.
|
|
LPSTR pszRootTimeStamp;
|
|
} HTTPMAILOPERATION, *LPHTTPMAILOPERATION;
|
|
|
|
class CHTTPMailTransport : public IHTTPMailTransport, public IXMLNodeFactory, public IHTTPMailTransport2
|
|
{
|
|
private:
|
|
ULONG m_cRef; // Reference Count
|
|
BOOL m_fHasServer; // Has been initialized with a server
|
|
BOOL m_fHasRootProps; // Root props have been retrieved
|
|
BOOL m_fTerminating; // in the terminating state...killing the iothread
|
|
IXPSTATUS m_status; // Connection status
|
|
HINTERNET m_hInternet; // Root wininet handle
|
|
HINTERNET m_hConnection; // Connection handle
|
|
LPSTR m_pszUserAgent; // user agent string
|
|
ILogFile *m_pLogFile; // Logfile Object
|
|
IHTTPMailCallback *m_pCallback; // Transport callback object
|
|
IXMLParser *m_pParser; // xml parser
|
|
HWND m_hwnd; // Window used for event synchronization
|
|
HANDLE m_hevPendingCommand; // Event object that signals a pending command
|
|
LPHTTPQUEUEDOP m_opPendingHead; // Pending operation - head of the queue
|
|
LPHTTPQUEUEDOP m_opPendingTail; // Pending operation - tail of the queue
|
|
CRITICAL_SECTION m_cs; // Thread Safety
|
|
HTTPMAILOPERATION m_op; // current operation
|
|
INETSERVER m_rServer; // Internet server
|
|
LPSTR m_pszCurrentHost; // current server
|
|
INTERNET_PORT m_nCurrentPort; // current port
|
|
ROOTPROPS m_rootProps;
|
|
public:
|
|
// ----------------------------------------------------------------------------
|
|
// Construction
|
|
// ----------------------------------------------------------------------------
|
|
CHTTPMailTransport(void);
|
|
virtual ~CHTTPMailTransport(void);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Unimplemented copy constructor and assignment operator
|
|
// ----------------------------------------------------------------------------
|
|
private:
|
|
CHTTPMailTransport(const CHTTPMailTransport& other); // intentionally unimplemented
|
|
CHTTPMailTransport& operator=(const CHTTPMailTransport& other); // intentionally unimplemented
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------------
|
|
// IUnknown methods
|
|
// ----------------------------------------------------------------------------
|
|
STDMETHODIMP QueryInterface(REFIID, LPVOID *);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// IInternetTransport methods
|
|
// ----------------------------------------------------------------------------
|
|
STDMETHODIMP Connect(LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging);
|
|
STDMETHODIMP DropConnection(void);
|
|
STDMETHODIMP Disconnect(void);
|
|
STDMETHODIMP IsState(IXPISSTATE isstate);
|
|
STDMETHODIMP GetServerInfo(LPINETSERVER pInetServer);
|
|
STDMETHODIMP_(IXPTYPE) GetIXPType(void);
|
|
STDMETHODIMP InetServerFromAccount(IImnAccount *pAccount, LPINETSERVER pInetServer);
|
|
STDMETHODIMP HandsOffCallback(void);
|
|
STDMETHODIMP GetStatus(IXPSTATUS *pCurrentStatus);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// IHTTPMailTransport methods
|
|
// ----------------------------------------------------------------------------
|
|
STDMETHODIMP InitNew(LPCSTR pszUserAgent, LPCSTR pszLogFilePath, IHTTPMailCallback *pCallback);
|
|
STDMETHODIMP GetProperty(HTTPMAILPROPTYPE proptype, LPSTR *ppszProp);
|
|
STDMETHODIMP GetPropertyDw(HTTPMAILPROPTYPE proptype, LPDWORD lpdwProp);
|
|
STDMETHODIMP CommandGET(LPCSTR pszPath, LPCSTR *rgszAcceptTypes, BOOL fTranslate, DWORD dwContext);
|
|
STDMETHODIMP CommandPUT(LPCSTR pszPath, LPVOID lpvData, ULONG cbData, DWORD dwContext);
|
|
STDMETHODIMP CommandPOST(LPCSTR pszPath, IStream *pStream, LPCSTR pszContentType, DWORD dwContext);
|
|
STDMETHODIMP CommandDELETE(LPCSTR pszPath, DWORD dwContext);
|
|
STDMETHODIMP CommandBDELETE(LPCSTR pszPath, LPHTTPTARGETLIST pBatchTargets, DWORD dwContext);
|
|
STDMETHODIMP CommandPROPFIND(LPCSTR pszUrl, IPropFindRequest *pRequest, DWORD dwDepth, DWORD dwContext);
|
|
STDMETHODIMP CommandPROPPATCH(LPCSTR pszUrl, IPropPatchRequest *pRequest, DWORD dwContext);
|
|
STDMETHODIMP CommandMKCOL(LPCSTR pszUrl, DWORD dwContext);
|
|
STDMETHODIMP CommandCOPY(LPCSTR pszPath, LPCSTR pszDestination, BOOL fAllowRename, DWORD dwContext);
|
|
STDMETHODIMP CommandBCOPY(LPCSTR pszSourceCollection, LPHTTPTARGETLIST pBatchTargets, LPCSTR pszDestCollection, LPHTTPTARGETLIST pBatchDests, BOOL fAllowRename, DWORD dwContext);
|
|
STDMETHODIMP CommandMOVE(LPCSTR pszPath, LPCSTR pszDestination, BOOL fAllowRename, DWORD dwContext);
|
|
STDMETHODIMP CommandBMOVE(LPCSTR pszSourceCollection, LPHTTPTARGETLIST pBatchTargets, LPCSTR pszDestCollection, LPHTTPTARGETLIST pBatchDests, BOOL fAllowRename, DWORD dwContext);
|
|
STDMETHODIMP MemberInfo(LPCSTR pszPath, MEMBERINFOFLAGS flags, DWORD dwDepth, BOOL fIncludeRoot, DWORD dwContext);
|
|
STDMETHODIMP FindFolders(LPCSTR pszPath, DWORD dwContext);
|
|
STDMETHODIMP MarkRead(LPCSTR pszPath, LPHTTPTARGETLIST pTargets, BOOL fMarkRead, DWORD dwContext);
|
|
STDMETHODIMP SendMessage(LPCSTR pszPath, LPCSTR pszFrom, LPHTTPTARGETLIST pTargets, BOOL fSaveInSent, IStream *pMessageStream, DWORD dwContext);
|
|
STDMETHODIMP ListContacts(LPCSTR pszPath, DWORD dwContext);
|
|
STDMETHODIMP ListContactInfos(LPCSTR pszCollectionPath, DWORD dwContext);
|
|
STDMETHODIMP ContactInfo(LPCSTR pszPath, DWORD dwContext);
|
|
STDMETHODIMP PostContact(LPCSTR pszPath, LPHTTPCONTACTINFO pciInfo, DWORD dwContext);
|
|
STDMETHODIMP PatchContact(LPCSTR pszPath, LPHTTPCONTACTINFO pciInfo, DWORD dwContext);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// IXMLNodeFactory methods
|
|
// ----------------------------------------------------------------------------
|
|
STDMETHODIMP NotifyEvent(IXMLNodeSource* pSource, XML_NODEFACTORY_EVENT iEvt);
|
|
STDMETHODIMP BeginChildren(IXMLNodeSource* pSource, XML_NODE_INFO *pNodeInfo);
|
|
STDMETHODIMP EndChildren(IXMLNodeSource* pSource, BOOL fEmpty, XML_NODE_INFO *pNodeInfo);
|
|
STDMETHODIMP Error(IXMLNodeSource* pSource, HRESULT hrErrorCode, USHORT cNumRecs, XML_NODE_INFO** apNodeInfo);
|
|
STDMETHODIMP CreateNode(
|
|
IXMLNodeSource* pSource,
|
|
PVOID pNodeParent,
|
|
USHORT cNumRecs,
|
|
XML_NODE_INFO** apNodeInfo);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// IHTTPMailTransport2 methods
|
|
// ----------------------------------------------------------------------------
|
|
STDMETHODIMP RootMemberInfo( LPCSTR pszPath, MEMBERINFOFLAGS flags, DWORD dwDepth,
|
|
BOOL fIncludeRoot, DWORD dwContext, LPSTR pszRootTimeStamp,
|
|
LPSTR pszInboxTimeStamp);
|
|
|
|
STDMETHODIMP FolderMemberInfo( LPCSTR pszPath, MEMBERINFOFLAGS flags, DWORD dwDepth, BOOL fIncludeRoot,
|
|
DWORD dwContext, LPSTR pszFolderTimeStamp, LPSTR pszFolderName);
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// New API
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT HrConnectToHost(LPSTR pszHostName, INTERNET_PORT nPort, LPSTR pszUserName, LPSTR pszPassword);
|
|
HRESULT DoLogonPrompt(void);
|
|
HRESULT DoGetParentWindow(HWND *phwndParent);
|
|
|
|
HINTERNET GetConnection(void) { return m_hConnection; }
|
|
LPSTR GetServerName(void) { return m_rServer.szServerName; }
|
|
LPSTR GetUserName(void) { return ('/0' == m_rServer.szUserName[0]) ? NULL : m_rServer.szUserName; }
|
|
LPSTR GetPassword(void) { return ('/0' == m_rServer.szPassword[0]) ? NULL : m_rServer.szPassword; }
|
|
|
|
IHTTPMailCallback* GetCallback(void) { return m_pCallback; }
|
|
|
|
HWND GetWindow(void) { return m_hwnd; }
|
|
|
|
BOOL GetHasRootProps(void) { return m_fHasRootProps; }
|
|
void SetHasRootProps(BOOL fHasRootProps) { m_fHasRootProps = fHasRootProps; }
|
|
|
|
LPSTR GetAdbar(void) { return m_rootProps.pszAdbar; }
|
|
void AdoptAdbar(LPSTR pszAdbar) { SafeMemFree(m_rootProps.pszAdbar); m_rootProps.pszAdbar = pszAdbar; }
|
|
|
|
LPSTR GetContacts(void) { return m_rootProps.pszContacts; }
|
|
void AdoptContacts(LPSTR pszContacts) { SafeMemFree(m_rootProps.pszContacts); m_rootProps.pszContacts = pszContacts; }
|
|
|
|
LPSTR GetInbox(void) { return m_rootProps.pszInbox; }
|
|
void AdoptInbox(LPSTR pszInbox) { SafeMemFree(m_rootProps.pszInbox); m_rootProps.pszInbox = pszInbox; }
|
|
|
|
LPSTR GetOutbox(void) { return m_rootProps.pszOutbox; }
|
|
void AdoptOutbox(LPSTR pszOutbox) { SafeMemFree(m_rootProps.pszOutbox); m_rootProps.pszOutbox = pszOutbox; }
|
|
|
|
LPSTR GetSendMsg(void) { return m_rootProps.pszSendMsg; }
|
|
void AdoptSendMsg(LPSTR pszSendMsg) { SafeMemFree(m_rootProps.pszSendMsg); m_rootProps.pszSendMsg = pszSendMsg; }
|
|
|
|
LPSTR GetSentItems(void) { return m_rootProps.pszSentItems; }
|
|
void AdoptSentItems(LPSTR pszSentItems) { SafeMemFree(m_rootProps.pszSentItems); m_rootProps.pszSentItems = pszSentItems; }
|
|
|
|
LPSTR GetDeletedItems(void) { return m_rootProps.pszDeletedItems; }
|
|
void AdoptDeletedItems(LPSTR pszDeletedItems) { SafeMemFree(m_rootProps.pszDeletedItems); m_rootProps.pszDeletedItems = pszDeletedItems; }
|
|
|
|
LPSTR GetDrafts(void) { return m_rootProps.pszDrafts; }
|
|
void AdoptDrafts(LPSTR pszDrafts) { SafeMemFree(m_rootProps.pszDrafts); m_rootProps.pszDrafts = pszDrafts; }
|
|
|
|
LPSTR GetMsgFolderRoot(void) { return m_rootProps.pszMsgFolderRoot; }
|
|
void AdoptMsgFolderRoot(LPSTR pszMsgFolderRoot) { SafeMemFree(m_rootProps.pszMsgFolderRoot); m_rootProps.pszMsgFolderRoot = pszMsgFolderRoot; }
|
|
|
|
LPSTR GetSig(void) { return m_rootProps.pszSig; }
|
|
void AdoptSig(LPSTR pszSig) { SafeMemFree(m_rootProps.pszSig); m_rootProps.pszSig = pszSig; }
|
|
|
|
BOOL WasAborted(void) { return m_op.fAborted; }
|
|
|
|
private:
|
|
// ----------------------------------------------------------------------------
|
|
// CHTTPMailTransport private implementation
|
|
// ----------------------------------------------------------------------------
|
|
public:
|
|
|
|
// Translate an HTTPCOMMAND constant into a string
|
|
LPSTR CommandToVerb(HTTPMAILCOMMAND command);
|
|
|
|
private:
|
|
HRESULT UpdateLogonInfo(void);
|
|
|
|
HRESULT GetParentWindow(HWND *phwndParent);
|
|
|
|
BOOL ReadBytes(LPSTR pszBuffer, DWORD cbBufferSize, DWORD *pcbBytesRead);
|
|
|
|
BOOL _GetStatusCode(DWORD *pdw);
|
|
BOOL _GetContentLength(DWORD *pdw);
|
|
|
|
HRESULT _GetRequestHeader(LPSTR *ppszHeader, DWORD dwHeader);
|
|
HRESULT _AddRequestHeader(LPCSTR pszHeader);
|
|
HRESULT _MemberInfo2(LPCSTR pszPath, MEMBERINFOFLAGS flags, DWORD dwDepth,
|
|
BOOL fIncludeRoot, DWORD dwContext, LPHTTPQUEUEDOP *ppOp);
|
|
HRESULT _HrParseAndCopy(LPCSTR pszToken, LPSTR *ppszDest, LPSTR lpszSrc);
|
|
HRESULT _HrGetTimestampHeader(LPSTR *ppszHeader);
|
|
|
|
|
|
BOOL _AuthCurrentRequest(DWORD dwStatus, BOOL fRetryAuth);
|
|
|
|
void _LogRequest(LPVOID pvData, DWORD cbData);
|
|
void _LogResponse(LPVOID pvData, DWORD cbData);
|
|
|
|
HRESULT QueueGetPropOperation(HTTPMAILPROPTYPE type);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Element Parsing
|
|
// ----------------------------------------------------------------------------
|
|
BOOL StackTop(HMELE hmEle) { return (m_op.dwStackDepth < ELE_STACK_CAPACITY) && (m_op.rgEleStack[m_op.dwStackDepth - 1].ele == hmEle); }
|
|
BOOL ValidStack(const HMELE *prgEle, DWORD cEle);
|
|
BOOL InValidElementChildren(void) { return ((m_op.dwStackDepth > 0) && (m_op.dwStackDepth <= ELE_STACK_CAPACITY) && (m_op.rgEleStack[m_op.dwStackDepth - 1].fBeganChildren)); }
|
|
void PopNamespaces(CXMLNamespace *pBaseNamespace);
|
|
HRESULT PushNamespaces(XML_NODE_INFO** apNodeInfo, USHORT cNumRecs);
|
|
|
|
HRESULT StrNToBoolW(const WCHAR *pwcText, ULONG ulLen, BOOL *pb);
|
|
HRESULT StatusStrNToIxpHr(const WCHAR *pwcText, DWORD ulLen, HRESULT *hr);
|
|
HRESULT AllocStrFromStrNW(const WCHAR *pwcText, ULONG ulLen, LPSTR *ppszAlloc);
|
|
HRESULT StrNToDwordW(const WCHAR *pwcText, ULONG ulLen, DWORD *pi);
|
|
HRESULT StrNToSpecialFolderW(const WCHAR *pwcText, ULONG ulLen, HTTPMAILSPECIALFOLDER *ptySpecial);
|
|
HRESULT StrNToContactTypeW(const WCHAR *pwcText, ULONG ulLen, HTTPMAILCONTACTTYPE *ptyContact);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Misc.
|
|
// ----------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------
|
|
// Queue Management
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT AllocQueuedOperation(
|
|
LPCSTR pszUrl,
|
|
LPVOID pvData,
|
|
ULONG cbDataLen,
|
|
LPHTTPQUEUEDOP *ppOp,
|
|
BOOL fAdoptData = FALSE);
|
|
void QueueOperation(LPHTTPQUEUEDOP pOp);
|
|
BOOL DequeueNextOperation(void);
|
|
|
|
void FlushQueue(void);
|
|
void TerminateIOThread(void);
|
|
|
|
BOOL IsTerminating(void)
|
|
{
|
|
BOOL fResult;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
fResult = m_fTerminating;
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
// Thread Entry Proxy
|
|
static DWORD CALLBACK IOThreadFuncProxy(PVOID pv);
|
|
|
|
DWORD IOThreadFunc();
|
|
|
|
// Window Proc
|
|
static LRESULT CALLBACK WndProc(
|
|
HWND hwnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam);
|
|
|
|
HRESULT HrReadCompleted(void);
|
|
|
|
// Reset the transport object
|
|
void Reset(void);
|
|
|
|
// Create a window handle for messaging between the client and i/o thread
|
|
BOOL CreateWnd(void);
|
|
|
|
// WinInet callback (proxies through StatusCallbackProxy)
|
|
void OnStatusCallback(
|
|
HINTERNET hInternet,
|
|
DWORD dwInternetStatus,
|
|
LPVOID pvStatusInformation,
|
|
DWORD dwStatusInformationLength);
|
|
|
|
// thunks the response to the calling thread
|
|
HRESULT _HrThunkConnectionError(void);
|
|
HRESULT _HrThunkConnectionError(DWORD dwStatus);
|
|
HRESULT _HrThunkResponse(BOOL fDone);
|
|
|
|
HRESULT InvokeResponseCallback(void);
|
|
|
|
// Translate a WinInet status message to an IXPSTATUS message.
|
|
// Returns true if the status was translated.
|
|
BOOL TranslateWinInetMsg(DWORD dwInternetStatus, IXPSTATUS *pIxpStatus);
|
|
|
|
// WinInet callback proxy, which calls through to non-static
|
|
// OnStatusCallback method
|
|
static void StatusCallbackProxy(
|
|
HINTERNET hInternet,
|
|
DWORD dwContext,
|
|
DWORD dwInternetStatus,
|
|
LPVOID pvStatusInformation,
|
|
DWORD dwStatusInformationLength);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Response Management
|
|
// ----------------------------------------------------------------------------
|
|
void FreeMemberInfoList(void);
|
|
void FreeMemberErrorList();
|
|
void FreeContactIdList(void);
|
|
void FreeContactInfoList(void);
|
|
void FreeBCopyMoveList(void);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// State Machine Functions
|
|
// ----------------------------------------------------------------------------
|
|
void DoOperation(void);
|
|
void FreeOperation(void);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Parser Utils
|
|
// ----------------------------------------------------------------------------
|
|
private:
|
|
HRESULT _BindToStruct(const WCHAR *pwcText,
|
|
ULONG ulLen,
|
|
const XPCOLUMN *prgCols,
|
|
DWORD cCols,
|
|
LPVOID pTarget,
|
|
BOOL *pfWasBound);
|
|
|
|
void _FreeStruct(const XPCOLUMN *prgCols,
|
|
DWORD cCols,
|
|
LPVOID pTarget,
|
|
DWORD *pdwFlags);
|
|
|
|
HRESULT _GetTextBuffer(LPPCDATABUFFER *ppTextBuffer)
|
|
{
|
|
if (m_op.pTextBuffer)
|
|
{
|
|
*ppTextBuffer = m_op.pTextBuffer;
|
|
m_op.pTextBuffer = NULL;
|
|
return S_OK;
|
|
}
|
|
else
|
|
return _AllocTextBuffer(ppTextBuffer);
|
|
}
|
|
|
|
HRESULT _AppendTextToBuffer(LPPCDATABUFFER pTextBuffer, const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT _AllocTextBuffer(LPPCDATABUFFER *ppTextBuffer);
|
|
void _ReleaseTextBuffer(LPPCDATABUFFER pTextBuffer)
|
|
{
|
|
IxpAssert(NULL != pTextBuffer);
|
|
|
|
// if the buffer capacity is the original byte count, and there is
|
|
// no buffer in the cache, then return this one to the cache
|
|
if (NULL == m_op.pTextBuffer && PCDATA_BUFSIZE == pTextBuffer->ulCapacity)
|
|
{
|
|
pTextBuffer->ulLen = 0;
|
|
m_op.pTextBuffer = pTextBuffer;
|
|
}
|
|
else
|
|
_FreeTextBuffer(pTextBuffer);
|
|
}
|
|
|
|
void _FreeTextBuffer(LPPCDATABUFFER pTextBuffer);
|
|
|
|
public:
|
|
// common states
|
|
HRESULT OpenRequest(void);
|
|
HRESULT SendRequest(void);
|
|
HRESULT AddCommonHeaders(void);
|
|
HRESULT RequireMultiStatus(void);
|
|
HRESULT FinalizeRequest(void);
|
|
HRESULT AddCharsetLine(void);
|
|
|
|
// GET states
|
|
HRESULT ProcessGetResponse(void);
|
|
|
|
// POST states
|
|
HRESULT AddContentTypeHeader(void);
|
|
HRESULT SendPostRequest(void);
|
|
HRESULT ProcessPostResponse(void);
|
|
|
|
// XML processing
|
|
HRESULT ProcessXMLResponse(void);
|
|
|
|
// PROPFIND states
|
|
HRESULT GeneratePropFindXML(void);
|
|
HRESULT AddDepthHeader(void);
|
|
|
|
// PROPPATCH states
|
|
HRESULT GeneratePropPatchXML(void);
|
|
|
|
// MKCOL states
|
|
HRESULT ProcessCreatedResponse(void);
|
|
|
|
// COPY and MOVE states
|
|
HRESULT AddDestinationHeader(void);
|
|
HRESULT ProcessLocationResponse(void);
|
|
|
|
// BCOPY and BMOVE states
|
|
HRESULT InitBCopyMove(void);
|
|
|
|
// RootProp states
|
|
HRESULT InitRootProps(void);
|
|
HRESULT FinalizeRootProps(void);
|
|
|
|
// MemberInfo states
|
|
HRESULT InitMemberInfo(void);
|
|
|
|
// MemberError states
|
|
HRESULT InitMemberError(void);
|
|
|
|
// ListContacts
|
|
HRESULT InitListContacts(void);
|
|
|
|
// ContactInfo
|
|
HRESULT InitContactInfo(void);
|
|
|
|
// PostContact
|
|
HRESULT ProcessPostContactResponse(void);
|
|
|
|
// PatchContact
|
|
HRESULT ProcessPatchContactResponse(void);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// XML Parsing Functions
|
|
// ----------------------------------------------------------------------------
|
|
HRESULT CreateElement(CXMLNamespace *pBaseNamespace, const WCHAR *pwcText, ULONG ulLen, ULONG ulNamespaceLen, BOOL fTerminal);
|
|
HRESULT EndChildren(void);
|
|
|
|
// BCOPY and BMOVE
|
|
HRESULT BCopyMove_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT BCopyMove_EndChildren(void);
|
|
|
|
// PropFind
|
|
HRESULT PropFind_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
|
|
// RootProps
|
|
HRESULT RootProps_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT RootProps_EndChildren(void);
|
|
|
|
// MemberInfo
|
|
HRESULT MemberInfo_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT MemberInfo_EndChildren(void);
|
|
|
|
// MemberError
|
|
HRESULT MemberError_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT MemberError_EndChildren(void);
|
|
|
|
// ListContacts
|
|
HRESULT ListContacts_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT ListContacts_EndChildren(void);
|
|
|
|
// ContactInfo
|
|
HRESULT ContactInfo_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT ContactInfo_EndChildren(void);
|
|
|
|
// PostContact and PatchContact
|
|
HRESULT PostOrPatchContact_HandleText(const WCHAR *pwcText, ULONG ulLen);
|
|
HRESULT PostOrPatchContact_EndChildren(void);
|
|
|
|
public:
|
|
HRESULT _CreateXMLParser(void);
|
|
};
|
|
|
|
#endif // __IXPHTTPM_H
|