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.

631 lines
27 KiB

  1. //***************************************************************************
  2. // IMAP4 Protocol Class Header File(CImap4Agent)
  3. // Written by Raymond Cheng, 3/21/96
  4. //
  5. // This class allows its callers to use IMAP4 client commands without concern
  6. // for the actual command syntax and without having to parse the response
  7. // from the IMAP4 server (which may contain information unrelated to the
  8. // original command).
  9. //
  10. // Given a server, this class makes a connection to the IMAP server when it
  11. // is first required, and retains this connection (periodically sending NoOps
  12. // if necessary) until this class is destroyed. Thus, for online usage, this
  13. // class should be retained throughout the entire session with the user. For
  14. // disconnected or offline operation, this class should be retained for only
  15. // as long as it takes to download new mail and synchronize the cache. After
  16. // these operations are complete, this class should be destroyed (which
  17. // closes the connection) before continuing with the user's mail session.
  18. //***************************************************************************
  19. #ifndef __IMAP4Protocol_H
  20. #define __IMAP4Protocol_H
  21. //---------------------------------------------------------------------------
  22. // CImap4Agent Required Includes
  23. //---------------------------------------------------------------------------
  24. #include "imnxport.h"
  25. #include "ASynConn.h"
  26. #include "ixpbase.h"
  27. #include "sicily.h"
  28. //---------------------------------------------------------------------------
  29. // CImap4Agent Forward Declarations
  30. //---------------------------------------------------------------------------
  31. class CImap4Agent;
  32. interface IMimeInternational;
  33. //---------------------------------------------------------------------------
  34. // CImap4Agent Constants and Defines
  35. //---------------------------------------------------------------------------
  36. const int CMDLINE_BUFSIZE = 512; // For command lines sent to IMAP server
  37. const int RESPLINE_BUFSIZE = 2048; // For lines received from IMAP server
  38. const int NUM_TAG_CHARS = 4;
  39. const boolean DONT_USE_UIDS = FALSE;
  40. const boolean USE_UIDS = TRUE;
  41. const BOOL USE_LAST_RESPONSE = TRUE;
  42. const BOOL DONT_USE_LAST_RESPONSE = FALSE;
  43. // IMAP-defined Transaction ID's
  44. const DWORD tidDONT_CARE = 0; // Means that transaction ID is unimportant or unavailable
  45. #define DEFAULT_CBHANDLER NULL // Pass this as a IIMAPCallback ptr if you wish to substitute
  46. // the default CB Handler (and make it clear to the reader)
  47. #define MAX_AUTH_TOKENS 32
  48. //---------------------------------------------------------------------------
  49. // CImap4Agent Data Types
  50. //---------------------------------------------------------------------------
  51. // The following are IMAP-specific HRESULTs.
  52. // When this is ready to roll in, these values will be migrated to Errors.h
  53. // Assert(FALSE) (placeholder)
  54. enum IMAP_HRESULT {
  55. hrIMAP_S_FOUNDLITERAL = 0,
  56. hrIMAP_S_NOTFOUNDLITERAL,
  57. hrIMAP_S_QUOTED,
  58. hrIMAP_S_ATOM,
  59. hrIMAP_S_NIL_NSTRING
  60. }; // IMAP_HRESULTS
  61. enum IMAP_COMMAND {
  62. icNO_COMMAND, // This indicates there are no cmds currently in progress
  63. icLOGIN_COMMAND,
  64. icCAPABILITY_COMMAND,
  65. icSELECT_COMMAND,
  66. icEXAMINE_COMMAND,
  67. icCREATE_COMMAND,
  68. icDELETE_COMMAND,
  69. icRENAME_COMMAND,
  70. icSUBSCRIBE_COMMAND,
  71. icUNSUBSCRIBE_COMMAND,
  72. icLIST_COMMAND,
  73. icLSUB_COMMAND,
  74. icAPPEND_COMMAND,
  75. icCLOSE_COMMAND,
  76. icEXPUNGE_COMMAND,
  77. icSEARCH_COMMAND,
  78. icFETCH_COMMAND,
  79. icSTORE_COMMAND,
  80. icCOPY_COMMAND,
  81. icLOGOUT_COMMAND,
  82. icNOOP_COMMAND,
  83. icAUTHENTICATE_COMMAND,
  84. icSTATUS_COMMAND,
  85. icIDLE_COMMAND,
  86. icALL_COMMANDS
  87. }; // IMAP_COMMAND
  88. enum IMAP_RESPONSE_ID {
  89. irNONE, // This represents an unknown IMAP response
  90. irOK_RESPONSE,
  91. irNO_RESPONSE,
  92. irBAD_RESPONSE,
  93. irCMD_CONTINUATION,
  94. irPREAUTH_RESPONSE,
  95. irBYE_RESPONSE,
  96. irCAPABILITY_RESPONSE,
  97. irLIST_RESPONSE,
  98. irLSUB_RESPONSE,
  99. irSEARCH_RESPONSE,
  100. irFLAGS_RESPONSE,
  101. irEXISTS_RESPONSE,
  102. irRECENT_RESPONSE,
  103. irEXPUNGE_RESPONSE,
  104. irFETCH_RESPONSE,
  105. irSTATUS_RESPONSE,
  106. irALERT_RESPONSECODE,
  107. irPARSE_RESPONSECODE,
  108. irPERMANENTFLAGS_RESPONSECODE,
  109. irREADWRITE_RESPONSECODE,
  110. irREADONLY_RESPONSECODE,
  111. irTRYCREATE_RESPONSECODE,
  112. irUIDVALIDITY_RESPONSECODE,
  113. irUNSEEN_RESPONSECODE
  114. }; // IMAP_RESPONSE_ID
  115. // States of the receiver FSM
  116. enum IMAP_RECV_STATE {
  117. irsUNINITIALIZED,
  118. irsNOT_CONNECTED,
  119. irsSVR_GREETING,
  120. irsIDLE,
  121. irsLITERAL,
  122. irsFETCH_BODY
  123. }; // IMAP_RECV_STATE
  124. enum IMAP_SEND_EVENT {
  125. iseSEND_COMMAND, // New command is available to be sent. Does nothing right now.
  126. iseSENDDONE, // Indicates receipt of AE_SENDDONE from CAsyncConn - we can send at will
  127. iseCMD_CONTINUATION, // Indicates server has given permission to send our literal
  128. iseUNPAUSE // Indicates that currently paused command may be unpaused
  129. }; // IMAP_SEND_EVENT
  130. enum IMAP_LINEFRAG_TYPE {
  131. iltLINE,
  132. iltLITERAL,
  133. iltRANGELIST,
  134. iltPAUSE,
  135. iltSTOP,
  136. iltLAST
  137. }; // IMAP_LINEFRAG_TYPE
  138. enum IMAP_LITERAL_STORETYPE {
  139. ilsSTRING,
  140. ilsSTREAM
  141. }; // IMAP_LITERAL_STORETYPE
  142. enum IMAP_PROTOCOL_STATUS {
  143. ipsNotConnected,
  144. ipsConnected,
  145. ipsAuthorizing,
  146. ipsAuthorized
  147. }; // IMAP_PROTOCOL_STATUS
  148. // The following is used to track what state the server SHOULD be in
  149. enum SERVERSTATE {ssNotConnected, ssConnecting, ssNonAuthenticated,
  150. ssAuthenticated, ssSelected};
  151. const DWORD INVALID_UID = 0;
  152. // Holds fragments of a command/response line to/from the IMAP server
  153. typedef struct tagIMAPLineFragment {
  154. IMAP_LINEFRAG_TYPE iltFragmentType; // We get/send lines and literals to/from IMAP svr
  155. IMAP_LITERAL_STORETYPE ilsLiteralStoreType; // Literals are stored as strings or streams
  156. DWORD dwLengthOfFragment;
  157. union {
  158. char *pszSource;
  159. LPSTREAM pstmSource;
  160. IRangeList *prlRangeList;
  161. } data;
  162. struct tagIMAPLineFragment *pilfNextFragment;
  163. struct tagIMAPLineFragment *pilfPrevFragment; // NB: I DO NOT update this after line is fully constructed
  164. } IMAP_LINE_FRAGMENT;
  165. // Points to first fragment in queue of fragments
  166. typedef struct tagIMAPLineFragmentQueue {
  167. IMAP_LINE_FRAGMENT *pilfFirstFragment; // Points to head of queue (this advances during transmission)
  168. IMAP_LINE_FRAGMENT *pilfLastFragment; // Points to tail of queue for quick enqueuing
  169. } IMAP_LINEFRAG_QUEUE;
  170. const IMAP_LINEFRAG_QUEUE ImapLinefragQueue_INIT = {NULL, NULL};
  171. enum AUTH_STATE {
  172. asUNINITIALIZED = 0,
  173. asWAITFOR_CONTINUE,
  174. asWAITFOR_CHALLENGE,
  175. asWAITFOR_AUTHENTICATION,
  176. asCANCEL_AUTHENTICATION
  177. }; // enum AUTH_STATE
  178. enum AUTH_EVENT {
  179. aeStartAuthentication = 0,
  180. aeOK_RESPONSE,
  181. aeBAD_OR_NO_RESPONSE,
  182. aeCONTINUE,
  183. aeABORT_AUTHENTICATION
  184. }; // enum AUTH_EVENT
  185. typedef struct tagAuthStatus {
  186. AUTH_STATE asCurrentState;
  187. BOOL fPromptForCredentials;
  188. int iCurrentAuthToken; // Ordinal (NOT index) of current auth token
  189. int iNumAuthTokens; // Num of auth mechanisms advertised by svr (rgpszAuthTokens)
  190. LPSTR rgpszAuthTokens[MAX_AUTH_TOKENS]; // Array of ptrs to auth mech strings
  191. SSPICONTEXT rSicInfo; // Data used for logging onto a sicily server
  192. LPSSPIPACKAGE pPackages; // Array of installed security packages
  193. ULONG cPackages; // Number of installed security packages (pPackages)
  194. } AUTH_STATUS;
  195. //***************************************************************************
  196. // CIMAPCmdInfo Class:
  197. // This class contains information about an IMAP command, such as a queue
  198. // of line fragments which constitute the actual command, the tag of the
  199. // command, and the transaction ID used to identify the command to the
  200. // CImap4Agent user.
  201. //***************************************************************************
  202. class CIMAPCmdInfo {
  203. public:
  204. // Constructor, Destructor
  205. CIMAPCmdInfo(CImap4Agent *pImap4Agent, IMAP_COMMAND icCmd,
  206. SERVERSTATE ssMinimumStateArg, WPARAM wParamArg,
  207. LPARAM lParamArg, IIMAPCallback *pCBHandlerArg);
  208. ~CIMAPCmdInfo(void);
  209. // Module variables
  210. IMAP_COMMAND icCommandID; // IMAP command currently in progress
  211. SERVERSTATE ssMinimumState; // Minimum server state for this cmd
  212. boolean fUIDRangeList; // TRUE if a UID rangelist is involved, FALSE by default
  213. char szTag[NUM_TAG_CHARS+1]; // Tag of currently executing command
  214. IMAP_LINEFRAG_QUEUE *pilqCmdLineQueue;
  215. WPARAM wParam; // User-supplied number which identifies this transaction
  216. LPARAM lParam; // User-supplied number which identifies this transaction
  217. IIMAPCallback *pCBHandler; // User-supplied CB handler (NULL means use default CB handler)
  218. CIMAPCmdInfo *piciNextCommand;
  219. private:
  220. CImap4Agent *m_pImap4Agent;
  221. }; // CIMAPCmdInfo
  222. //---------------------------------------------------------------------------
  223. // CImap4Agent Class Definition
  224. //---------------------------------------------------------------------------
  225. class CImap4Agent :
  226. public IIMAPTransport2,
  227. public CIxpBase
  228. {
  229. friend CIMAPCmdInfo;
  230. public:
  231. //***********************************************************************
  232. // Public Section
  233. //***********************************************************************
  234. // Constructor/Destructor
  235. CImap4Agent(void);
  236. ~CImap4Agent(void);
  237. HRESULT STDMETHODCALLTYPE SetWindow(void);
  238. HRESULT STDMETHODCALLTYPE ResetWindow(void);
  239. // IUnknown Methods
  240. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);
  241. ULONG STDMETHODCALLTYPE AddRef(void);
  242. ULONG STDMETHODCALLTYPE Release(void);
  243. // IASyncConnCB Method
  244. void OnNotify(ASYNCSTATE asOld, ASYNCSTATE asNew, ASYNCEVENT ae);
  245. // Administration Functions
  246. HRESULT STDMETHODCALLTYPE InitNew(LPSTR pszLogFilePath, IIMAPCallback *pCBHandler);
  247. HRESULT STDMETHODCALLTYPE HandsOffCallback(void);
  248. HRESULT STDMETHODCALLTYPE SetDefaultCBHandler(IIMAPCallback *pCBHandler);
  249. // Utility Functions
  250. HRESULT STDMETHODCALLTYPE NewIRangeList(IRangeList **pprlNewRangeList);
  251. // IIMAPTransport functions
  252. // IMAP Client Commands, in same order of definition as in RFC-1730
  253. // Not all commands are available, as some commands are used exclusively
  254. // inside this class and thus need not be exported.
  255. HRESULT STDMETHODCALLTYPE Capability(DWORD *pdwCapabilityFlags);
  256. HRESULT STDMETHODCALLTYPE Select(WPARAM wParam, LPARAM lParam,
  257. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  258. HRESULT STDMETHODCALLTYPE Examine(WPARAM wParam, LPARAM lParam,
  259. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  260. HRESULT STDMETHODCALLTYPE Create(WPARAM wParam, LPARAM lParam,
  261. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  262. HRESULT STDMETHODCALLTYPE Delete(WPARAM wParam, LPARAM lParam,
  263. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  264. HRESULT STDMETHODCALLTYPE Rename(WPARAM wParam, LPARAM lParam,
  265. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName, LPSTR lpszNewMailboxName);
  266. HRESULT STDMETHODCALLTYPE Subscribe(WPARAM wParam, LPARAM lParam,
  267. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  268. HRESULT STDMETHODCALLTYPE Unsubscribe(WPARAM wParam, LPARAM lParam,
  269. IIMAPCallback *pCBHandler, LPSTR lpszMailboxName);
  270. HRESULT STDMETHODCALLTYPE List(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  271. LPSTR lpszMailboxNameReference, LPSTR lpszMailboxNamePattern);
  272. HRESULT STDMETHODCALLTYPE Lsub(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  273. LPSTR lpszMailboxNameReference, LPSTR lpszMailboxNamePattern);
  274. HRESULT STDMETHODCALLTYPE Append(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  275. LPSTR lpszMailboxName, LPSTR lpszMessageFlags, FILETIME ftMessageDateTime,
  276. LPSTREAM lpstmMessageToSave);
  277. HRESULT STDMETHODCALLTYPE Close(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler);
  278. HRESULT STDMETHODCALLTYPE Expunge(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler);
  279. HRESULT STDMETHODCALLTYPE Search(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  280. LPSTR lpszSearchCriteria, boolean bReturnUIDs, IRangeList *pMsgRange,
  281. boolean bUIDRangeList);
  282. HRESULT STDMETHODCALLTYPE Fetch(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  283. IRangeList *pMsgRange, boolean bUIDMsgRange, LPSTR lpszFetchArgs);
  284. HRESULT STDMETHODCALLTYPE Store(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  285. IRangeList *pMsgRange, boolean bUIDRangeList, LPSTR lpszStoreArgs);
  286. HRESULT STDMETHODCALLTYPE Copy(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler,
  287. IRangeList *pMsgRange, boolean bUIDRangeList, LPSTR lpszMailboxName);
  288. HRESULT STDMETHODCALLTYPE Status(WPARAM wParam, LPARAM lParam,
  289. IIMAPCallback *pCBHandler, LPSTR pszMailboxName, LPSTR pszStatusCmdArgs);
  290. HRESULT STDMETHODCALLTYPE Noop(WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler);
  291. DWORD GenerateMsgSet(LPSTR lpszDestination, DWORD dwSizeOfDestination,
  292. DWORD *pMsgID, DWORD cMsgID);
  293. // Message Sequence Number to UID member functions - the caller may use
  294. // these functions to map from MSN's to UID's, if the caller uses UIDs
  295. // to refer to messages. If the caller uses MSN's, there is no need to
  296. // invoke the following functions.
  297. HRESULT STDMETHODCALLTYPE ResizeMsgSeqNumTable(DWORD dwSizeOfMbox);
  298. HRESULT STDMETHODCALLTYPE UpdateSeqNumToUID(DWORD dwMsgSeqNum, DWORD dwUID);
  299. HRESULT STDMETHODCALLTYPE RemoveSequenceNum(DWORD dwDeletedMsgSeqNum);
  300. HRESULT STDMETHODCALLTYPE MsgSeqNumToUID(DWORD dwMsgSeqNum, DWORD *pdwUID);
  301. HRESULT STDMETHODCALLTYPE GetMsgSeqNumToUIDArray(DWORD **ppdwMsgSeqNumToUIDArray,
  302. DWORD *pdwNumberOfElements);
  303. HRESULT STDMETHODCALLTYPE GetHighestMsgSeqNum(DWORD *pdwHighestMSN);
  304. HRESULT STDMETHODCALLTYPE ResetMsgSeqNumToUID(void);
  305. // IInternetTransport functions
  306. HRESULT STDMETHODCALLTYPE GetServerInfo(LPINETSERVER pInetServer);
  307. IXPTYPE STDMETHODCALLTYPE GetIXPType(void);
  308. HRESULT STDMETHODCALLTYPE IsState(IXPISSTATE isstate);
  309. HRESULT STDMETHODCALLTYPE InetServerFromAccount(IImnAccount *pAccount,
  310. LPINETSERVER pInetServer);
  311. HRESULT STDMETHODCALLTYPE Connect(LPINETSERVER pInetServer,
  312. boolean fAuthenticate, boolean fCommandLogging);
  313. HRESULT STDMETHODCALLTYPE Disconnect(void);
  314. HRESULT STDMETHODCALLTYPE DropConnection(void);
  315. HRESULT STDMETHODCALLTYPE GetStatus(IXPSTATUS *pCurrentStatus);
  316. // IIMAPTransport2 functions
  317. HRESULT STDMETHODCALLTYPE SetDefaultCP(DWORD dwTranslateFlags, UINT uiCodePage);
  318. HRESULT STDMETHODCALLTYPE MultiByteToModifiedUTF7(LPCSTR pszSource,
  319. LPSTR *ppszDestination, UINT uiSourceCP, DWORD dwFlags);
  320. HRESULT STDMETHODCALLTYPE ModifiedUTF7ToMultiByte(LPCSTR pszSource,
  321. LPSTR *ppszDestination, UINT uiDestinationCP, DWORD dwFlags);
  322. HRESULT STDMETHODCALLTYPE SetIdleMode(DWORD dwIdleFlags);
  323. HRESULT STDMETHODCALLTYPE EnableFetchEx(DWORD dwFetchExFlags);
  324. protected:
  325. // CIxpBase [pure] virtual functions
  326. void OnDisconnected(void);
  327. void ResetBase(void);
  328. void DoQuit(void);
  329. void OnEnterBusy(void);
  330. void OnLeaveBusy(void);
  331. private:
  332. //***********************************************************************
  333. // Private Section
  334. //***********************************************************************
  335. //---------------------------------------------------------------------------
  336. // Module Data Types
  337. //---------------------------------------------------------------------------
  338. //---------------------------------------------------------------------------
  339. // Module Variables
  340. //---------------------------------------------------------------------------
  341. SERVERSTATE m_ssServerState; // Tracks server state to catch bad usage of module
  342. DWORD m_dwCapabilityFlags; // Bit-flags indicate capabilities supported by
  343. // both us and the server
  344. char m_szLastResponseText[RESPLINE_BUFSIZE]; // Holds human-readable text of
  345. // last server response
  346. LONG m_lRefCount; // Reference count for this module
  347. IIMAPCallback *m_pCBHandler; // Object containing all callbacks for this class
  348. IMAP_RECV_STATE m_irsState; // State of receiver FSM
  349. boolean m_bFreeToSend; // Set to TRUE by send subsystem when hrWouldBlock returned
  350. boolean m_fIDLE; // Set to TRUE when server has accepted our IDLE command
  351. IMAP_LINEFRAG_QUEUE m_ilqRecvQueue; // Received fragments placed here until ready to parse
  352. // Critical Sections: to avoid deadlock, if more than one CS must be entered, enter them
  353. // in the order listed below. Note that CIxpBase::m_cs should always be entered FIRST.
  354. CRITICAL_SECTION m_csTag; // Protects static szCurrentTag var in GenerateCommandTag()
  355. CRITICAL_SECTION m_csSendQueue; // Protects command send queue
  356. CRITICAL_SECTION m_csPendingList; // Protects list of pending commands
  357. IMAP_LINE_FRAGMENT *m_pilfLiteralInProgress; // Literals in progress live here until finished
  358. DWORD m_dwLiteralInProgressBytesLeft; // This tells us when we're finished
  359. FETCH_BODY_PART m_fbpFetchBodyPartInProgress; // Allows us to persist data during body part download
  360. DWORD m_dwAppendStreamUploaded; // Num bytes already uploaded during APPEND, for progress
  361. DWORD m_dwAppendStreamTotal; // Size of stream uploaded during APPEND, for progress indication
  362. boolean m_bCurrentMboxReadOnly; // For debugging purposes (verify proper access requests)
  363. CIMAPCmdInfo *m_piciSendQueue; // Queue of commands waiting to be sent
  364. CIMAPCmdInfo *m_piciPendingList; // List of commands pending server response
  365. CIMAPCmdInfo *m_piciCmdInSending; // The command in m_piciSendQueue currently being sent to server
  366. IMimeInternational *m_pInternational; // MIME object for international conversions
  367. DWORD m_dwTranslateMboxFlags;
  368. UINT m_uiDefaultCP;
  369. AUTH_STATUS m_asAuthStatus;
  370. // Message Sequence Number to UID mapping variables
  371. DWORD *m_pdwMsgSeqNumToUID;
  372. DWORD m_dwSizeOfMsgSeqNumToUID;
  373. DWORD m_dwHighestMsgSeqNum;
  374. DWORD m_dwFetchFlags;
  375. //---------------------------------------------------------------------------
  376. // Internal Module Functions
  377. //---------------------------------------------------------------------------
  378. // IMAP Response-Parsing Functions
  379. HRESULT ParseSvrResponseLine (IMAP_LINE_FRAGMENT **ppilfLine,
  380. boolean *lpbTaggedResponse, LPSTR lpszTagFromSvr,
  381. IMAP_RESPONSE_ID *pirParseResult);
  382. HRESULT ParseStatusResponse (LPSTR lpszStatusResponseLine,
  383. IMAP_RESPONSE_ID *pirParseResult);
  384. HRESULT ParseResponseCode(LPSTR lpszResponseCode);
  385. HRESULT ParseSvrMboxResponse (IMAP_LINE_FRAGMENT **ppilfLine,
  386. LPSTR lpszSvrMboxResponseLine, IMAP_RESPONSE_ID *pirParseResult);
  387. HRESULT ParseMsgStatusResponse (IMAP_LINE_FRAGMENT **ppilfLine,
  388. LPSTR lpszMsgResponseLine, IMAP_RESPONSE_ID *pirParseResult);
  389. HRESULT ParseListLsubResponse(IMAP_LINE_FRAGMENT **ppilfLine,
  390. LPSTR lpszListResponse, IMAP_RESPONSE_ID irListLsubID);
  391. IMAP_MBOXFLAGS ParseMboxFlag(LPSTR lpszFlagToken);
  392. HRESULT ParseFetchResponse (IMAP_LINE_FRAGMENT **ppilfLine,
  393. DWORD dwMsgSeqNum, LPSTR lpszFetchResp);
  394. HRESULT ParseSearchResponse(LPSTR lpszSearchResponse);
  395. HRESULT ParseMsgFlagList(LPSTR lpszStartOfFlagList,
  396. IMAP_MSGFLAGS *lpmfMsgFlags, LPDWORD lpdwNumBytesRead);
  397. void parseCapability (LPSTR lpszCapabilityToken);
  398. void AddAuthMechanism(LPSTR pszAuthMechanism);
  399. HRESULT ParseMboxStatusResponse(IMAP_LINE_FRAGMENT **ppilfLine, LPSTR pszStatusResponse);
  400. HRESULT ParseEnvelope(FETCH_CMD_RESULTS_EX *pEnvResults, IMAP_LINE_FRAGMENT **ppilfLine,
  401. LPSTR *ppCurrent);
  402. HRESULT ParseIMAPAddresses(IMAPADDR **ppiaResults, IMAP_LINE_FRAGMENT **ppilfLine,
  403. LPSTR *ppCurrent);
  404. void DowngradeFetchResponse(FETCH_CMD_RESULTS *pfcrOldFetchStruct,
  405. FETCH_CMD_RESULTS_EX *pfcreNewFetchStruct);
  406. // IMAP String-Conversion Functions
  407. HRESULT QuotedToString(LPSTR *ppszDestinationBuf, LPDWORD pdwSizeOfDestination,
  408. LPSTR *ppCurrentSrcPos);
  409. HRESULT AStringToString(IMAP_LINE_FRAGMENT **ppilfLine,
  410. LPSTR *ppszDestination, LPDWORD pdwSizeOfDestination, LPSTR *ppCurrentSrcPos);
  411. inline boolean isTEXT_CHAR(char c);
  412. inline boolean isATOM_CHAR(char c);
  413. HRESULT NStringToString(IMAP_LINE_FRAGMENT **ppilfLine,
  414. LPSTR *ppszDestination, LPDWORD pdwLengthOfDestination, LPSTR *ppCurrentSrcPos);
  415. HRESULT NStringToStream(IMAP_LINE_FRAGMENT **ppilfLine,
  416. LPSTREAM *ppstmResult, LPSTR *ppCurrentSrcPos);
  417. HRESULT AppendSendAString(CIMAPCmdInfo *piciCommand, LPSTR lpszCommandLine,
  418. LPSTR *ppCmdLinePos, DWORD dwSizeOfCommandLine, LPCSTR lpszSource,
  419. BOOL fPrependSpace = TRUE);
  420. HRESULT StringToQuoted(LPSTR lpszDestination, LPCSTR lpszSource,
  421. DWORD dwSizeOfDestination, LPDWORD lpdwNumCharsWritten);
  422. inline boolean isPrintableUSASCII(BOOL fUnicode, LPCSTR pszIn);
  423. inline boolean isIMAPModifiedBase64(const char c);
  424. inline boolean isEqualUSASCII(BOOL fUnicode, LPCSTR pszIn, const char c);
  425. inline void SetUSASCIIChar(BOOL fUnicode, LPSTR pszOut, char cUSASCII);
  426. HRESULT NonUSStringToModifiedUTF7(UINT uiCurrentACP, LPCSTR pszStartOfNonUSASCII,
  427. int iLengthOfNonUSASCII, LPSTR *ppszOut, LPINT piNumCharsWritten);
  428. HRESULT UnicodeToUSASCII(LPSTR *ppszUSASCII, LPCWSTR pwszUnicode,
  429. DWORD dwSrcLenInBytes, LPDWORD pdwUSASCIILen);
  430. HRESULT ASCIIToUnicode(LPWSTR *ppwszUnicode, LPCSTR pszASCII, DWORD dwSrcLen);
  431. HRESULT _MultiByteToModifiedUTF7(LPCSTR pszSource, LPSTR *ppszDestination);
  432. HRESULT _ModifiedUTF7ToMultiByte(LPCSTR pszSource, LPSTR *ppszDestination);
  433. HRESULT ConvertString(UINT uiSourceCP, UINT uiDestCP, LPCSTR pszSource, int *piSrcLen,
  434. LPSTR *ppszDest, int *piDestLen, int iOutputExtra);
  435. HRESULT HandleFailedTranslation(BOOL fUnicode, BOOL fToUTF7, LPCSTR pszSource, LPSTR *ppszDest);
  436. // IMAP Command Construction Function
  437. void GenerateCommandTag(LPSTR lpszTag);
  438. HRESULT OneArgCommand(LPCSTR lpszCommandVerb, LPSTR lpszMboxName,
  439. IMAP_COMMAND icCommandID, WPARAM wParam, LPARAM lParam,
  440. IIMAPCallback *pCBHandler);
  441. HRESULT NoArgCommand(LPCSTR lpszCommandVerb, IMAP_COMMAND icCommandID,
  442. SERVERSTATE ssMinimumState, WPARAM wParam, LPARAM lParam,
  443. IIMAPCallback *pCBHandler);
  444. HRESULT TwoArgCommand(LPCSTR lpszCommandVerb, LPCSTR lpszFirstArg,
  445. LPCSTR lpszSecondArg, IMAP_COMMAND icCommandID,
  446. SERVERSTATE ssMinimumState, WPARAM wParam, LPARAM lParam,
  447. IIMAPCallback *pCBHandler);
  448. HRESULT RangedCommand(LPCSTR lpszCommandVerb, boolean bUIDPrefix,
  449. IRangeList *pMsgRange, boolean bUIDRangeList, boolean bAStringCmdArgs,
  450. LPSTR lpszCmdArgs, IMAP_COMMAND icCommandID, WPARAM wParam, LPARAM lParam,
  451. IIMAPCallback *pCBHandler);
  452. HRESULT TwoMailboxCommand(LPCSTR lpszCommandVerb, LPSTR lpszFirstMbox,
  453. LPSTR lpszSecondMbox, IMAP_COMMAND icCommandID, SERVERSTATE ssMinimumState,
  454. WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler);
  455. void AppendMsgRange(LPSTR *ppDest, const DWORD cchSizeDest, const DWORD idStartOfRange,
  456. const DWORD idEndOfRange, boolean bSuppressComma);
  457. void EnterIdleMode(void);
  458. // IMAP Fragment Manipulation Functions
  459. void EnqueueFragment(IMAP_LINE_FRAGMENT *pilfSourceFragment,
  460. IMAP_LINEFRAG_QUEUE *pilqLineFragQueue);
  461. void InsertFragmentBeforePause(IMAP_LINE_FRAGMENT *pilfSourceFragment,
  462. IMAP_LINEFRAG_QUEUE *pilqLineFragQueue);
  463. IMAP_LINE_FRAGMENT *DequeueFragment(IMAP_LINEFRAG_QUEUE *pilqLineFraqQueue);
  464. boolean NextFragmentIsLiteral(IMAP_LINEFRAG_QUEUE *pilqLineFragQueue);
  465. void FreeFragment(IMAP_LINE_FRAGMENT **ppilfFragment);
  466. // IMAP Receiver Functions
  467. void AddPendingCommand(CIMAPCmdInfo *piciNewCommand);
  468. CIMAPCmdInfo *RemovePendingCommand(LPSTR pszTag);
  469. WORD FindTransactionID (WPARAM *pwParam, LPARAM *plParam,
  470. IIMAPCallback **ppCBHandler, IMAP_COMMAND icTarget1,
  471. IMAP_COMMAND icTarget2 = icNO_COMMAND);
  472. void ProcessServerGreeting(char *pszResponseLine, DWORD dwNumBytesReceived);
  473. void OnCommandCompletion(LPSTR szTag, HRESULT hrCompletionResult,
  474. IMAP_RESPONSE_ID irCompletionResponse);
  475. void CheckForCompleteResponse(LPSTR pszResponseLine, DWORD dwNumBytesRead,
  476. IMAP_RESPONSE_ID *pirParseResult);
  477. void AddBytesToLiteral(LPSTR pszResponseBuf, DWORD dwNumBytesRead);
  478. HRESULT ProcessResponseLine(void);
  479. void GetTransactionID(WPARAM *pwParam, LPARAM *plParam,
  480. IIMAPCallback **ppCBHandler, IMAP_RESPONSE_ID irResponseType);
  481. HRESULT PrepareForLiteral(DWORD dwSizeOfLiteral);
  482. void PrepareForFetchBody(DWORD dwMsgSeqNum, DWORD dwSizeOfLiteral, LPSTR pszBodyTag);
  483. BOOL isFetchResponse(IMAP_LINEFRAG_QUEUE *pilqCurrentResponse, LPDWORD pdwMsgSeqNum);
  484. BOOL isFetchBodyLiteral(IMAP_LINE_FRAGMENT *pilfCurrent, LPSTR pszStartOfLiteralSize,
  485. LPSTR *ppszBodyTag);
  486. void DispatchFetchBodyPart(LPSTR pszResponseBuf, DWORD dwNumBytesRead,
  487. BOOL fFreeBodyTagAtEnd);
  488. void UploadStreamProgress(DWORD dwBytesUploaded);
  489. // IMAP Authentication Functions
  490. HRESULT GetAccountInfo(void);
  491. void LoginUser(void);
  492. void ReLoginUser(void);
  493. void AuthenticateUser(AUTH_EVENT aeEvent, LPSTR pszServerData, DWORD dwSizeOfData);
  494. HRESULT TryAuthMethod(BOOL fNextAuthMethod, UINT *puiFailureTextID);
  495. HRESULT CancelAuthentication(void);
  496. void FreeAuthStatus(void);
  497. // IMAP Send Functions
  498. CIMAPCmdInfo *DequeueCommand(void);
  499. void ProcessSendQueue(IMAP_SEND_EVENT iseEvent);
  500. HRESULT SendCmdLine(CIMAPCmdInfo *piciCommand, DWORD dwFlags,
  501. LPCSTR lpszCommandText, DWORD dwCmdLineLength);
  502. HRESULT SendLiteral(CIMAPCmdInfo *piciCommand, LPSTREAM pstmLiteral,
  503. DWORD dwSizeOfStream);
  504. HRESULT SendRangelist(CIMAPCmdInfo *piciCommand, IRangeList *pRangeList,
  505. boolean bUIDRangeList);
  506. HRESULT SendPause(CIMAPCmdInfo *piciCommand);
  507. HRESULT SendStop(CIMAPCmdInfo *piciCommand);
  508. HRESULT SubmitIMAPCommand(CIMAPCmdInfo *picfCommand);
  509. void GetNextCmdToSend(void);
  510. boolean isValidNonWaitingCmdSequence(void);
  511. boolean CanStreamCommand(IMAP_COMMAND icCommandID);
  512. void CompressCommand(CIMAPCmdInfo *pici);
  513. // Miscellaneous Helper Functions
  514. void OnIMAPError(HRESULT hrResult, LPSTR pszFailureText,
  515. BOOL bIncludeLastResponse, LPSTR pszDetails = NULL);
  516. void FreeAllData(HRESULT hrTerminatedCmdResult);
  517. void OnIMAPResponse(IIMAPCallback *pCBHandler, IMAP_RESPONSE *pirIMAPResponse);
  518. void FreeFetchResponse(FETCH_CMD_RESULTS_EX *pcreFreeMe);
  519. void FreeIMAPAddresses(IMAPADDR *piaFreeMe);
  520. }; // CIMAP4 Class
  521. #endif // #ifdef __IMAP4Protocol_H