1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include "nsCOMPtr.h"
5 #include "objbase.h"
6 #include "nsISupports.h"
7 
8 #include "mozilla/ModuleUtils.h"
9 #include "mozilla/Services.h"
10 #include "nsIObserverService.h"
11 #include "nsIAppStartupNotifier.h"
12 #include "Registry.h"
13 #include "msgMapiSupport.h"
14 
15 #include "msgMapiImp.h"
16 
17 /** Implementation of the nsIMapiSupport interface.
18  *  Use standard implementation of nsISupports stuff.
19  */
20 
NS_IMPL_ISUPPORTS(nsMapiSupport,nsIMapiSupport,nsIObserver)21 NS_IMPL_ISUPPORTS(nsMapiSupport, nsIMapiSupport, nsIObserver)
22 
23 NS_IMETHODIMP
24 nsMapiSupport::Observe(nsISupports* aSubject, const char* aTopic,
25                        const char16_t* aData) {
26   nsresult rv = NS_OK;
27 
28   if (!strcmp(aTopic, "profile-after-change")) return InitializeMAPISupport();
29 
30   if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
31     return ShutdownMAPISupport();
32 
33   nsCOMPtr<nsIObserverService> observerService =
34       mozilla::services::GetObserverService();
35   NS_ENSURE_TRUE(observerService, NS_ERROR_UNEXPECTED);
36 
37   rv = observerService->AddObserver(this, "profile-after-change", false);
38   if (NS_FAILED(rv)) return rv;
39 
40   rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
41   if (NS_FAILED(rv)) return rv;
42 
43   return rv;
44 }
45 
nsMapiSupport()46 nsMapiSupport::nsMapiSupport() : m_dwRegister(0), m_nsMapiFactory(nullptr) {}
47 
~nsMapiSupport()48 nsMapiSupport::~nsMapiSupport() {}
49 
50 NS_IMETHODIMP
InitializeMAPISupport()51 nsMapiSupport::InitializeMAPISupport() {
52   ::OleInitialize(nullptr);
53 
54   if (m_nsMapiFactory ==
55       nullptr)  // No Registering if already done.  Sanity Check!!
56   {
57     m_nsMapiFactory = new CMapiFactory();
58 
59     if (m_nsMapiFactory != nullptr) {
60       HRESULT hr = ::CoRegisterClassObject(CLSID_CMapiImp, m_nsMapiFactory,
61                                            CLSCTX_LOCAL_SERVER,
62                                            REGCLS_MULTIPLEUSE, &m_dwRegister);
63 
64       if (FAILED(hr)) {
65         m_nsMapiFactory->Release();
66         m_nsMapiFactory = nullptr;
67         return NS_ERROR_FAILURE;
68       }
69     }
70   }
71 
72   return NS_OK;
73 }
74 
75 NS_IMETHODIMP
ShutdownMAPISupport()76 nsMapiSupport::ShutdownMAPISupport() {
77   if (m_dwRegister != 0) ::CoRevokeClassObject(m_dwRegister);
78 
79   if (m_nsMapiFactory != nullptr) {
80     m_nsMapiFactory->Release();
81     m_nsMapiFactory = nullptr;
82   }
83 
84   ::OleUninitialize();
85 
86   return NS_OK;
87 }
88 
89 NS_IMETHODIMP
RegisterServer()90 nsMapiSupport::RegisterServer() {
91   // TODO: Figure out what kind of error propagation to pass back
92   ::RegisterServer(CLSID_CMapiImp, L"Mozilla MAPI", L"MozillaMapi",
93                    L"MozillaMapi.1");
94   return NS_OK;
95 }
96 
97 NS_IMETHODIMP
UnRegisterServer()98 nsMapiSupport::UnRegisterServer() {
99   // TODO: Figure out what kind of error propagation to pass back
100   ::UnregisterServer(CLSID_CMapiImp, L"MozillaMapi", L"MozillaMapi.1");
101   return NS_OK;
102 }
103 
104 NS_DEFINE_NAMED_CID(NS_IMAPISUPPORT_CID);
105 
106 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMapiSupport)
107 
108 static const mozilla::Module::CategoryEntry kMAPICategories[] = {
109     {
110         APPSTARTUP_CATEGORY,
111         "Mapi Support",
112         "service," NS_IMAPISUPPORT_CONTRACTID,
113     },
114     {NULL}};
115 
116 const mozilla::Module::CIDEntry kMAPICIDs[] = {
117     {&kNS_IMAPISUPPORT_CID, false, NULL, nsMapiSupportConstructor}, {NULL}};
118 
119 const mozilla::Module::ContractIDEntry kMAPIContracts[] = {
120     {NS_IMAPISUPPORT_CONTRACTID, &kNS_IMAPISUPPORT_CID}, {NULL}};
121 
122 extern const mozilla::Module kMAPIModule = {
123     mozilla::Module::kVersion, kMAPICIDs, kMAPIContracts, kMAPICategories};
124