1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef MapiApi_h___
6 #define MapiApi_h___
7 
8 #include "nscore.h"
9 #include "nsString.h"
10 #include "nsTArray.h"
11 
12 #include <stdio.h>
13 
14 #include <windows.h>
15 #include <mapi.h>
16 #include <mapix.h>
17 #include <mapidefs.h>
18 #include <mapicode.h>
19 #include <mapitags.h>
20 #include <mapiutil.h>
21 // wabutil.h expects mapiutil to define _MAPIUTIL_H but it actually
22 // defines _MAPIUTIL_H_
23 #define _MAPIUTIL_H
24 
25 #ifndef PR_INTERNET_CPID
26 #  define PR_INTERNET_CPID (PROP_TAG(PT_LONG, 0x3FDE))
27 #endif
28 #ifndef MAPI_NATIVE_BODY
29 #  define MAPI_NATIVE_BODY (0x00010000)
30 #endif
31 #ifndef MAPI_NATIVE_BODY_TYPE_RTF
32 #  define MAPI_NATIVE_BODY_TYPE_RTF (0x00000001)
33 #endif
34 #ifndef MAPI_NATIVE_BODY_TYPE_HTML
35 #  define MAPI_NATIVE_BODY_TYPE_HTML (0x00000002)
36 #endif
37 #ifndef MAPI_NATIVE_BODY_TYPE_PLAINTEXT
38 #  define MAPI_NATIVE_BODY_TYPE_PLAINTEXT (0x00000004)
39 #endif
40 #ifndef PR_BODY_HTML_A
41 #  define PR_BODY_HTML_A (PROP_TAG(PT_STRING8, 0x1013))
42 #endif
43 #ifndef PR_BODY_HTML_W
44 #  define PR_BODY_HTML_W (PROP_TAG(PT_UNICODE, 0x1013))
45 #endif
46 #ifndef PR_BODY_HTML
47 #  define PR_BODY_HTML (PROP_TAG(PT_TSTRING, 0x1013))
48 #endif
49 
50 class CMapiFolderList;
51 class CMsgStore;
52 class CMapiFolder;
53 
54 class CMapiContentIter {
55  public:
56   virtual BOOL HandleContentItem(ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
57 };
58 
59 class CMapiHierarchyIter {
60  public:
61   virtual BOOL HandleHierarchyItem(ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
62 };
63 
64 class CMapiApi {
65  public:
66   CMapiApi();
67   ~CMapiApi();
68 
69   static BOOL LoadMapi(void);
70   static BOOL LoadMapiEntryPoints(void);
71   static void UnloadMapi(void);
72 
73   static HINSTANCE m_hMapi32;
74 
75   static void MAPIUninitialize(void);
76   static HRESULT MAPIInitialize(LPVOID lpInit);
77   static SCODE MAPIAllocateBuffer(ULONG cbSize, LPVOID FAR* lppBuffer);
78   static ULONG MAPIFreeBuffer(LPVOID lpBuff);
79   static HRESULT MAPILogonEx(ULONG ulUIParam, LPTSTR lpszProfileName,
80                              LPTSTR lpszPassword, FLAGS flFlags,
81                              LPMAPISESSION FAR* lppSession);
82   static HRESULT OpenStreamOnFile(LPALLOCATEBUFFER lpAllocateBuffer,
83                                   LPFREEBUFFER lpFreeBuffer, ULONG ulFlags,
84                                   LPCTSTR lpszFileName, LPTSTR lpszPrefix,
85                                   LPSTREAM FAR* lppStream);
86   static void FreeProws(LPSRowSet prows);
87 
88   BOOL Initialize(void);
89   BOOL LogOn(void);
90 
91   void AddMessageStore(CMsgStore* pStore);
SetCurrentMsgStore(LPMDB lpMdb)92   void SetCurrentMsgStore(LPMDB lpMdb) { m_lpMdb = lpMdb; }
93 
94   // Open any given entry from the current Message Store
95   BOOL OpenEntry(ULONG cbEntry, LPENTRYID pEntryId, LPUNKNOWN* ppOpen);
96   static BOOL OpenMdbEntry(LPMDB lpMdb, ULONG cbEntry, LPENTRYID pEntryId,
97                            LPUNKNOWN* ppOpen);
98 
99   // Fill in the folders list with the hierarchy from the given
100   // message store.
101   BOOL GetStoreFolders(ULONG cbEid, LPENTRYID lpEid, CMapiFolderList& folders,
102                        int startDepth);
103   BOOL GetStoreAddressFolders(ULONG cbEid, LPENTRYID lpEid,
104                               CMapiFolderList& folders);
105   BOOL OpenStore(ULONG cbEid, LPENTRYID lpEid, LPMDB* ppMdb);
106 
107   // Iteration
108   BOOL IterateStores(CMapiFolderList& list);
109   BOOL IterateContents(CMapiContentIter* pIter, LPMAPIFOLDER pFolder,
110                        ULONG flags = 0);
111   BOOL IterateHierarchy(CMapiHierarchyIter* pIter, LPMAPIFOLDER pFolder,
112                         ULONG flags = 0);
113 
114   // Properties
115   static LPSPropValue GetMapiProperty(LPMAPIPROP pProp, ULONG tag);
116   // If delVal is true, functions will call CMapiApi::MAPIFreeBuffer on pVal.
117   static BOOL GetEntryIdFromProp(LPSPropValue pVal, ULONG& cbEntryId,
118                                  LPENTRYID& lpEntryId, BOOL delVal = TRUE);
119   static BOOL GetStringFromProp(LPSPropValue pVal, nsCString& val,
120                                 BOOL delVal = TRUE);
121   static BOOL GetStringFromProp(LPSPropValue pVal, nsString& val,
122                                 BOOL delVal = TRUE);
123   static LONG GetLongFromProp(LPSPropValue pVal, BOOL delVal = TRUE);
124   static BOOL GetLargeStringProperty(LPMAPIPROP pProp, ULONG tag,
125                                      nsCString& val);
126   static BOOL GetLargeStringProperty(LPMAPIPROP pProp, ULONG tag,
127                                      nsString& val);
128   static BOOL IsLargeProperty(LPSPropValue pVal);
129   static ULONG GetEmailPropertyTag(LPMAPIPROP lpProp, LONG nameID);
130 
131   static BOOL GetRTFPropertyDecodedAsUTF16(LPMAPIPROP pProp, nsString& val,
132                                            unsigned long& nativeBodyType,
133                                            unsigned long codepage = 0);
134 
135   // Debugging & reporting stuff
136   static void ListProperties(LPMAPIPROP lpProp, BOOL getValues = TRUE);
137   static void ListPropertyValue(LPSPropValue pVal, nsCString& s);
138 
139  protected:
140   BOOL HandleHierarchyItem(ULONG oType, ULONG cb, LPENTRYID pEntry);
141   BOOL HandleContentsItem(ULONG oType, ULONG cb, LPENTRYID pEntry);
142   void GetStoreInfo(CMapiFolder* pFolder, long* pSzContents);
143 
144   // array of available message stores, cached so that
145   // message stores are only opened once, preventing multiple
146   // logon's by the user if the store requires a logon.
147   CMsgStore* FindMessageStore(ULONG cbEid, LPENTRYID lpEid);
148   void ClearMessageStores(void);
149 
150   static void CStrToUnicode(const char* pStr, nsString& result);
151 
152   // Debugging & reporting stuff
153   static void GetPropTagName(ULONG tag, nsCString& s);
154   static void ReportStringProp(const char* pTag, LPSPropValue pVal);
155   static void ReportUIDProp(const char* pTag, LPSPropValue pVal);
156   static void ReportLongProp(const char* pTag, LPSPropValue pVal);
157 
158  private:
159   static int m_clients;
160   static BOOL m_initialized;
161   static nsTArray<CMsgStore*>* m_pStores;
162   static LPMAPISESSION m_lpSession;
163   static LPMDB m_lpMdb;
164   static HRESULT m_lastError;
165   static char16_t* m_pUniBuff;
166   static int m_uniBuffLen;
167 
168   static BOOL GetLargeProperty(LPMAPIPROP pProp, ULONG tag, void** result);
169 };
170 
171 class CMapiFolder {
172  public:
173   CMapiFolder();
174   explicit CMapiFolder(const CMapiFolder* pCopyFrom);
175   CMapiFolder(const char16_t* pDisplayName, ULONG cbEid, LPENTRYID lpEid,
176               int depth, LONG oType = MAPI_FOLDER);
177   ~CMapiFolder();
178 
SetDoImport(BOOL doIt)179   void SetDoImport(BOOL doIt) { m_doImport = doIt; }
SetObjectType(long oType)180   void SetObjectType(long oType) { m_objectType = oType; }
SetDisplayName(const char16_t * pDisplayName)181   void SetDisplayName(const char16_t* pDisplayName) {
182     m_displayName = pDisplayName;
183   }
184   void SetEntryID(ULONG cbEid, LPENTRYID lpEid);
SetDepth(int depth)185   void SetDepth(int depth) { m_depth = depth; }
SetFilePath(const char16_t * pFilePath)186   void SetFilePath(const char16_t* pFilePath) { m_mailFilePath = pFilePath; }
187 
GetDoImport(void)188   BOOL GetDoImport(void) const { return m_doImport; }
GetObjectType(void)189   LONG GetObjectType(void) const { return m_objectType; }
GetDisplayName(nsString & name)190   void GetDisplayName(nsString& name) const { name = m_displayName; }
GetFilePath(nsString & path)191   void GetFilePath(nsString& path) const { path = m_mailFilePath; }
IsStore(void)192   BOOL IsStore(void) const { return m_objectType == MAPI_STORE; }
IsFolder(void)193   BOOL IsFolder(void) const { return m_objectType == MAPI_FOLDER; }
GetDepth(void)194   int GetDepth(void) const { return m_depth; }
195 
196   LPENTRYID GetEntryID(ULONG* pCb = NULL) const {
197     if (pCb) *pCb = m_cbEid;
198     return (LPENTRYID)m_lpEid;
199   }
GetCBEntryID(void)200   ULONG GetCBEntryID(void) const { return m_cbEid; }
201 
202  private:
203   LONG m_objectType;
204   ULONG m_cbEid;
205   BYTE* m_lpEid;
206   nsString m_displayName;
207   int m_depth;
208   nsString m_mailFilePath;
209   BOOL m_doImport;
210 };
211 
212 class CMapiFolderList {
213  public:
214   CMapiFolderList();
215   ~CMapiFolderList();
216 
217   void AddItem(CMapiFolder* pFolder);
GetItem(int index)218   CMapiFolder* GetItem(int index) {
219     if ((index >= 0) && (index < (int)m_array.Length()))
220       return GetAt(index);
221     else
222       return NULL;
223   }
224   void ClearAll(void);
225 
226   // Debugging and reporting
227   void DumpList(void);
228 
GetAt(int index)229   CMapiFolder* GetAt(int index) { return m_array.ElementAt(index); }
GetSize(void)230   int GetSize(void) { return m_array.Length(); }
231 
232  protected:
233   void EnsureUniqueName(CMapiFolder* pFolder);
234   void GenerateFilePath(CMapiFolder* pFolder);
235   void ChangeName(nsString& name);
236 
237  private:
238   nsTArray<CMapiFolder*> m_array;
239 };
240 
241 class CMsgStore {
242  public:
243   explicit CMsgStore(ULONG cbEid = 0, LPENTRYID lpEid = NULL);
244   ~CMsgStore();
245 
246   void SetEntryID(ULONG cbEid, LPENTRYID lpEid);
247   BOOL Open(LPMAPISESSION pSession, LPMDB* ppMdb);
248 
GetCBEntryID(void)249   ULONG GetCBEntryID(void) { return m_cbEid; }
GetLPEntryID(void)250   LPENTRYID GetLPEntryID(void) { return (LPENTRYID)m_lpEid; }
251 
252  private:
253   ULONG m_cbEid;
254   BYTE* m_lpEid;
255   LPMDB m_lpMdb;
256 };
257 
258 class CMapiFolderContents {
259  public:
260   CMapiFolderContents(LPMDB lpMdb, ULONG cbEID, LPENTRYID lpEid);
261   ~CMapiFolderContents();
262 
263   BOOL GetNext(ULONG* pcbEid, LPENTRYID* ppEid, ULONG* poType, BOOL* pDone);
264 
GetCount(void)265   ULONG GetCount(void) { return m_count; }
266 
267  protected:
268   BOOL SetUpIter(void);
269 
270  private:
271   HRESULT m_lastError;
272   BOOL m_failure;
273   LPMDB m_lpMdb;
274   LPMAPIFOLDER m_lpFolder;
275   LPMAPITABLE m_lpTable;
276   ULONG m_fCbEid;
277   BYTE* m_fLpEid;
278   ULONG m_count;
279   ULONG m_iterCount;
280   BYTE* m_lastLpEid;
281   ULONG m_lastCbEid;
282 };
283 
284 #endif /* MapiApi_h__ */
285