// -------------------------------------------------------------------------------- // Ixphttpm.h // Copyright (c)1998 Microsoft Corporation, All Rights Reserved // Greg Friedman // -------------------------------------------------------------------------------- #ifndef __IXPHTTPM_H #define __IXPHTTPM_H // -------------------------------------------------------------------------------- // Includes // -------------------------------------------------------------------------------- #include // 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 in a 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