summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/import/src/MapiApi.h
blob: 4d9dc7be2a9df321f7b07f48c3210162a1e0d13d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MapiApi_h___
#define MapiApi_h___

#include "nscore.h"
#include "nsString.h"
#include "nsTArray.h"

#include <stdio.h>

#include <windows.h>
#include <mapi.h>
#include <mapix.h>
#include <mapidefs.h>
#include <mapicode.h>
#include <mapitags.h>
#include <mapiutil.h>
// wabutil.h expects mapiutil to define _MAPIUTIL_H but it actually
// defines _MAPIUTIL_H_
#define _MAPIUTIL_H

#ifndef PR_INTERNET_CPID
#  define PR_INTERNET_CPID (PROP_TAG(PT_LONG, 0x3FDE))
#endif
#ifndef MAPI_NATIVE_BODY
#  define MAPI_NATIVE_BODY (0x00010000)
#endif
#ifndef MAPI_NATIVE_BODY_TYPE_RTF
#  define MAPI_NATIVE_BODY_TYPE_RTF (0x00000001)
#endif
#ifndef MAPI_NATIVE_BODY_TYPE_HTML
#  define MAPI_NATIVE_BODY_TYPE_HTML (0x00000002)
#endif
#ifndef MAPI_NATIVE_BODY_TYPE_PLAINTEXT
#  define MAPI_NATIVE_BODY_TYPE_PLAINTEXT (0x00000004)
#endif
#ifndef PR_BODY_HTML_A
#  define PR_BODY_HTML_A (PROP_TAG(PT_STRING8, 0x1013))
#endif
#ifndef PR_BODY_HTML_W
#  define PR_BODY_HTML_W (PROP_TAG(PT_UNICODE, 0x1013))
#endif
#ifndef PR_BODY_HTML
#  define PR_BODY_HTML (PROP_TAG(PT_TSTRING, 0x1013))
#endif

class CMapiFolderList;
class CMsgStore;
class CMapiFolder;

class CMapiContentIter {
 public:
  virtual BOOL HandleContentItem(ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
};

class CMapiHierarchyIter {
 public:
  virtual BOOL HandleHierarchyItem(ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
};

class CMapiApi {
 public:
  CMapiApi();
  ~CMapiApi();

  static BOOL LoadMapi(void);
  static BOOL LoadMapiEntryPoints(void);
  static void UnloadMapi(void);

  static HINSTANCE m_hMapi32;

  static void MAPIUninitialize(void);
  static HRESULT MAPIInitialize(LPVOID lpInit);
  static SCODE MAPIAllocateBuffer(ULONG cbSize, LPVOID FAR* lppBuffer);
  static ULONG MAPIFreeBuffer(LPVOID lpBuff);
  static HRESULT MAPILogonEx(ULONG ulUIParam, LPTSTR lpszProfileName,
                             LPTSTR lpszPassword, FLAGS flFlags,
                             LPMAPISESSION FAR* lppSession);
  static HRESULT OpenStreamOnFile(LPALLOCATEBUFFER lpAllocateBuffer,
                                  LPFREEBUFFER lpFreeBuffer, ULONG ulFlags,
                                  LPCTSTR lpszFileName, LPTSTR lpszPrefix,
                                  LPSTREAM FAR* lppStream);
  static void FreeProws(LPSRowSet prows);

  BOOL Initialize(void);
  BOOL LogOn(void);

  void AddMessageStore(CMsgStore* pStore);
  void SetCurrentMsgStore(LPMDB lpMdb) { m_lpMdb = lpMdb; }

  // Open any given entry from the current Message Store
  BOOL OpenEntry(ULONG cbEntry, LPENTRYID pEntryId, LPUNKNOWN* ppOpen);
  static BOOL OpenMdbEntry(LPMDB lpMdb, ULONG cbEntry, LPENTRYID pEntryId,
                           LPUNKNOWN* ppOpen);

  // Fill in the folders list with the hierarchy from the given
  // message store.
  BOOL GetStoreFolders(ULONG cbEid, LPENTRYID lpEid, CMapiFolderList& folders,
                       int startDepth);
  BOOL GetStoreAddressFolders(ULONG cbEid, LPENTRYID lpEid,
                              CMapiFolderList& folders);
  BOOL OpenStore(ULONG cbEid, LPENTRYID lpEid, LPMDB* ppMdb);

  // Iteration
  BOOL IterateStores(CMapiFolderList& list);
  BOOL IterateContents(CMapiContentIter* pIter, LPMAPIFOLDER pFolder,
                       ULONG flags = 0);
  BOOL IterateHierarchy(CMapiHierarchyIter* pIter, LPMAPIFOLDER pFolder,
                        ULONG flags = 0);

  // Properties
  static LPSPropValue GetMapiProperty(LPMAPIPROP pProp, ULONG tag);
  // If delVal is true, functions will call CMapiApi::MAPIFreeBuffer on pVal.
  static BOOL GetEntryIdFromProp(LPSPropValue pVal, ULONG& cbEntryId,
                                 LPENTRYID& lpEntryId, BOOL delVal = TRUE);
  static BOOL GetStringFromProp(LPSPropValue pVal, nsCString& val,
                                BOOL delVal = TRUE);
  static BOOL GetStringFromProp(LPSPropValue pVal, nsString& val,
                                BOOL delVal = TRUE);
  static LONG GetLongFromProp(LPSPropValue pVal, BOOL delVal = TRUE);
  static BOOL GetLargeStringProperty(LPMAPIPROP pProp, ULONG tag,
                                     nsCString& val);
  static BOOL GetLargeStringProperty(LPMAPIPROP pProp, ULONG tag,
                                     nsString& val);
  static BOOL IsLargeProperty(LPSPropValue pVal);
  static ULONG GetEmailPropertyTag(LPMAPIPROP lpProp, LONG nameID);

  static BOOL GetRTFPropertyDecodedAsUTF16(LPMAPIPROP pProp, nsString& val,
                                           unsigned long& nativeBodyType,
                                           unsigned long codepage = 0);

  // Debugging & reporting stuff
  static void ListProperties(LPMAPIPROP lpProp, BOOL getValues = TRUE);
  static void ListPropertyValue(LPSPropValue pVal, nsCString& s);

 protected:
  BOOL HandleHierarchyItem(ULONG oType, ULONG cb, LPENTRYID pEntry);
  BOOL HandleContentsItem(ULONG oType, ULONG cb, LPENTRYID pEntry);
  void GetStoreInfo(CMapiFolder* pFolder, long* pSzContents);

  // array of available message stores, cached so that
  // message stores are only opened once, preventing multiple
  // logon's by the user if the store requires a logon.
  CMsgStore* FindMessageStore(ULONG cbEid, LPENTRYID lpEid);
  void ClearMessageStores(void);

  static void CStrToUnicode(const char* pStr, nsString& result);

  // Debugging & reporting stuff
  static void GetPropTagName(ULONG tag, nsCString& s);
  static void ReportStringProp(const char* pTag, LPSPropValue pVal);
  static void ReportUIDProp(const char* pTag, LPSPropValue pVal);
  static void ReportLongProp(const char* pTag, LPSPropValue pVal);

 private:
  static int m_clients;
  static BOOL m_initialized;
  static nsTArray<CMsgStore*>* m_pStores;
  static LPMAPISESSION m_lpSession;
  static LPMDB m_lpMdb;
  static HRESULT m_lastError;
  static char16_t* m_pUniBuff;
  static int m_uniBuffLen;

  static BOOL GetLargeProperty(LPMAPIPROP pProp, ULONG tag, void** result);
};

class CMapiFolder {
 public:
  CMapiFolder();
  explicit CMapiFolder(const CMapiFolder* pCopyFrom);
  CMapiFolder(const char16_t* pDisplayName, ULONG cbEid, LPENTRYID lpEid,
              int depth, LONG oType = MAPI_FOLDER);
  ~CMapiFolder();

  void SetDoImport(BOOL doIt) { m_doImport = doIt; }
  void SetObjectType(long oType) { m_objectType = oType; }
  void SetDisplayName(const char16_t* pDisplayName) {
    m_displayName = pDisplayName;
  }
  void SetEntryID(ULONG cbEid, LPENTRYID lpEid);
  void SetDepth(int depth) { m_depth = depth; }
  void SetFilePath(const char16_t* pFilePath) { m_mailFilePath = pFilePath; }

  BOOL GetDoImport(void) const { return m_doImport; }
  LONG GetObjectType(void) const { return m_objectType; }
  void GetDisplayName(nsString& name) const { name = m_displayName; }
  void GetFilePath(nsString& path) const { path = m_mailFilePath; }
  BOOL IsStore(void) const { return m_objectType == MAPI_STORE; }
  BOOL IsFolder(void) const { return m_objectType == MAPI_FOLDER; }
  int GetDepth(void) const { return m_depth; }

  LPENTRYID GetEntryID(ULONG* pCb = NULL) const {
    if (pCb) *pCb = m_cbEid;
    return (LPENTRYID)m_lpEid;
  }
  ULONG GetCBEntryID(void) const { return m_cbEid; }

 private:
  LONG m_objectType;
  ULONG m_cbEid;
  BYTE* m_lpEid;
  nsString m_displayName;
  int m_depth;
  nsString m_mailFilePath;
  BOOL m_doImport;
};

class CMapiFolderList {
 public:
  CMapiFolderList();
  ~CMapiFolderList();

  void AddItem(CMapiFolder* pFolder);
  CMapiFolder* GetItem(int index) {
    if ((index >= 0) && (index < (int)m_array.Length()))
      return GetAt(index);
    else
      return NULL;
  }
  void ClearAll(void);

  // Debugging and reporting
  void DumpList(void);

  CMapiFolder* GetAt(int index) { return m_array.ElementAt(index); }
  int GetSize(void) { return m_array.Length(); }

 protected:
  void EnsureUniqueName(CMapiFolder* pFolder);
  void GenerateFilePath(CMapiFolder* pFolder);
  void ChangeName(nsString& name);

 private:
  nsTArray<CMapiFolder*> m_array;
};

class CMsgStore {
 public:
  explicit CMsgStore(ULONG cbEid = 0, LPENTRYID lpEid = NULL);
  ~CMsgStore();

  void SetEntryID(ULONG cbEid, LPENTRYID lpEid);
  BOOL Open(LPMAPISESSION pSession, LPMDB* ppMdb);

  ULONG GetCBEntryID(void) { return m_cbEid; }
  LPENTRYID GetLPEntryID(void) { return (LPENTRYID)m_lpEid; }

 private:
  ULONG m_cbEid;
  BYTE* m_lpEid;
  LPMDB m_lpMdb;
};

class CMapiFolderContents {
 public:
  CMapiFolderContents(LPMDB lpMdb, ULONG cbEID, LPENTRYID lpEid);
  ~CMapiFolderContents();

  BOOL GetNext(ULONG* pcbEid, LPENTRYID* ppEid, ULONG* poType, BOOL* pDone);

  ULONG GetCount(void) { return m_count; }

 protected:
  BOOL SetUpIter(void);

 private:
  HRESULT m_lastError;
  BOOL m_failure;
  LPMDB m_lpMdb;
  LPMAPIFOLDER m_lpFolder;
  LPMAPITABLE m_lpTable;
  ULONG m_fCbEid;
  BYTE* m_fLpEid;
  ULONG m_count;
  ULONG m_iterCount;
  BYTE* m_lastLpEid;
  ULONG m_lastCbEid;
};

#endif /* MapiApi_h__ */