summaryrefslogtreecommitdiff
path: root/mailnews/import/outlook/src/MapiApi.h
blob: 8b59b80d81f34b1860863921cc7e4ade5c0f345e (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
/* -*- 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 "nsStringGlue.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, LPTSTR 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();
  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:
  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__ */