diff --git a/mailnews/base/public/nsIMapiRegistry.idl b/mailnews/base/public/nsIMapiRegistry.idl new file mode 100644 index 00000000000..d5a2d7af9f6 --- /dev/null +++ b/mailnews/base/public/nsIMapiRegistry.idl @@ -0,0 +1,70 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIDOMWindow; + +/** + * This interface provides support for registering Mozilla as the default + * Mail Client. This interface can also be used to get/set the user preference + * for the default Mail Client. + * + */ +[scriptable, uuid(c5be14ba-4e0a-4eec-a1b8-04363761d63c)] +interface nsIMapiRegistry: nsISupports { + + /** This is set to TRUE if Mozilla is the default Application + */ + attribute boolean isDefaultMailClient; + + /** This is set TRUE only once per session. + */ + readonly attribute boolean showDialog; + + /** This will bring the dialog asking the user if he/she wants to set + * Mozilla as default Mail Client. + * Call this only if Mozilla is not the default Mail client + */ + void showMailIntegrationDialog(in nsIDOMWindow parentWindow); + +}; + +%{C++ +#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1" +#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry" +%} diff --git a/mailnews/mapi/mapihook/build/.cvsignore b/mailnews/mapi/mapihook/build/.cvsignore new file mode 100644 index 00000000000..d64e867aede --- /dev/null +++ b/mailnews/mapi/mapihook/build/.cvsignore @@ -0,0 +1,4 @@ +dlldata.c +msgMapi.h +msgMapi_i.c +msgMapi_p.c diff --git a/mailnews/mapi/mapihook/build/MapiProxy.def b/mailnews/mapi/mapihook/build/MapiProxy.def new file mode 100644 index 00000000000..a5ba81c5af0 --- /dev/null +++ b/mailnews/mapi/mapihook/build/MapiProxy.def @@ -0,0 +1,47 @@ +; ***** BEGIN LICENSE BLOCK ***** +; Version: MPL 1.1/GPL 2.0/LGPL 2.1 +; +; The contents of this file are subject to the Mozilla Public License Version +; 1.1 (the "License"); you may not use this file except in compliance with +; the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" basis, +; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +; for the specific language governing rights and limitations under the +; License. +; +; The Original Code is Mozilla. +; +; The Initial Developer of the Original Code is +; Netscape Communications Corp. +; Portions created by the Initial Developer are Copyright (C) 2001 +; the Initial Developer. All Rights Reserved. +; +; Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) +; +; Alternatively, the contents of this file may be used under the terms of +; either the GNU General Public License Version 2 or later (the "GPL"), or +; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +; in which case the provisions of the GPL or the LGPL are applicable instead +; of those above. If you wish to allow use of your version of this file only +; under the terms of either the GPL or the LGPL, and not to allow others to +; use your version of this file under the terms of the MPL, indicate your +; decision by deleting the provisions above and replace them with the notice +; and other provisions required by the GPL or the LGPL. If you do not delete +; the provisions above, a recipient may use your version of this file under +; the terms of any one of the MPL, the GPL or the LGPL. +; +; ***** END LICENSE BLOCK ***** + +LIBRARY MapiProxy.dll +DESCRIPTION 'Proxy/Stub DLL' + +EXPORTS + DllGetClassObject @1 PRIVATE + DllCanUnloadNow @2 PRIVATE + GetProxyDllInfo @3 PRIVATE + DllRegisterServer @4 PRIVATE + DllUnregisterServer @5 PRIVATE + + diff --git a/mailnews/mapi/mapihook/build/makefile.win b/mailnews/mapi/mapihook/build/makefile.win new file mode 100644 index 00000000000..2d42cf9645d --- /dev/null +++ b/mailnews/mapi/mapihook/build/makefile.win @@ -0,0 +1,68 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Mozilla. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corp. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH=..\..\..\.. + +MODULE = MapiProxy +EXPORT_LIBRARY = $(MODULE) +LIBRARY_NAME = $(MODULE) +DEFFILE = MapiProxy.def + +include <$(DEPTH)\config\config.mak> + +################################################################## + +LCFLAGS=-DREGISTER_PROXY_DLL -DUNICODE -D_UNICODE + +OBJS= .\$(OBJDIR)\dlldata.obj \ + .\$(OBJDIR)\msgMapi_p.obj \ + .\$(OBJDIR)\msgMapi_i.obj \ + $(NULL) + +WIN_LIBS= rpcrt4.lib + +EXPORTS= msgMapi.h \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +msgMapi.h msgMapi_p.c msgMapi_i.c dlldata.c : msgMapi.idl + midl $(UNICODE_FLAGS) msgMapi.idl + +clobber:: + rm -f dlldata.c msgMapi_i.c msgMapi_p.c msgMapi.h + + diff --git a/mailnews/mapi/mapihook/build/msgMapi.idl b/mailnews/mapi/mapihook/build/msgMapi.idl new file mode 100644 index 00000000000..62f217cc85e --- /dev/null +++ b/mailnews/mapi/mapihook/build/msgMapi.idl @@ -0,0 +1,114 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * Contributor(s): Rajiv Dayal (rdayal@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// This idl will be compiled by MIDL. MS-COM is used +// as brdige between MAPI clients and the Mozilla. + +import "unknwn.idl"; + +typedef wchar_t LOGIN_PW_TYPE[256]; + +typedef struct +{ + unsigned long ulReserved; + unsigned long flFlags; /* Flags */ + unsigned long nPosition_NotUsed; /* character in text to be replaced by attachment */ + LPTSTR lpszPathName; /* Full path name including file name */ + LPTSTR lpszFileName; /* Real (original) file name */ + unsigned char * lpFileType_NotUsed ; +} nsMapiFileDesc, * lpnsMapiFileDesc; + + +typedef struct +{ + unsigned long ulReserved; + unsigned long ulRecipClass; /* MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG */ + LPTSTR lpszName; /* Recipient name to display */ + LPTSTR lpszAddress; /* Recipient email address */ + unsigned long ulEIDSize_NotUsed; + unsigned char * lpEntryID_NotUsed ; +} nsMapiRecipDesc, * lpnsMapiRecipDesc; + +typedef struct +{ + unsigned long ulReserved; + LPTSTR lpszSubject; /* Message Subject */ + LPTSTR lpszNoteText; /* Message Text */ + LPTSTR lpszMessageType_NotUsed; + LPTSTR lpszDateReceived_notUsed; /* in YYYY/MM/DD HH:MM format */ + LPTSTR lpszConversationID_NotUsed; /* conversation thread ID */ + unsigned long flFlags; /* unread,return receipt */ + lpnsMapiRecipDesc lpOriginator; /* Originator descriptor */ + unsigned long nRecipCount; /* Number of recipients */ + lpnsMapiRecipDesc lpRecips; /* Recipient descriptors */ + unsigned long nFileCount; /* # of file attachments */ + lpnsMapiFileDesc lpFiles; /* Attachment descriptors */ +} nsMapiMessage, * lpnsMapiMessage; + + +[ + object, + uuid(6EDCD38E-8861-11d5-A3DD-00B0D0F3BAA7), + helpstring("nsIMapi Inteface"), + pointer_default(unique) +] + +interface nsIMapi : IUnknown +{ + HRESULT Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin, + LOGIN_PW_TYPE aPassWord, unsigned long aFlags, + [out] unsigned long *aSessionId); + + HRESULT Initialize(); + HRESULT IsValid(); + HRESULT IsValidSession([in] unsigned long aSession); + + HRESULT SendMail([in] unsigned long aSession, [in] lpnsMapiMessage aMessage, + [in] short aRecipCount, [in, size_is(aRecipCount)] lpnsMapiRecipDesc aRecips, + [in] short aFileCount, [in, size_is(aFileCount)] lpnsMapiFileDesc aFiles, + [in] unsigned long aFlags, [in] unsigned long aReserved) ; + + HRESULT SendDocuments( [in] unsigned long aSession, + [in] LPTSTR aDelimChar, [in] LPTSTR aFilePaths, + [in] LPTSTR aFileNames, [in] ULONG aFlags ) ; + + HRESULT Logoff (unsigned long aSession); + HRESULT CleanUp(); +}; + + + diff --git a/mailnews/mapi/mapihook/makefile.win b/mailnews/mapi/mapihook/makefile.win new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mailnews/mapi/mapihook/public/makefile.win b/mailnews/mapi/mapihook/public/makefile.win new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mailnews/mapi/mapihook/public/nsIMapiRegistry.idl b/mailnews/mapi/mapihook/public/nsIMapiRegistry.idl new file mode 100644 index 00000000000..d5a2d7af9f6 --- /dev/null +++ b/mailnews/mapi/mapihook/public/nsIMapiRegistry.idl @@ -0,0 +1,70 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIDOMWindow; + +/** + * This interface provides support for registering Mozilla as the default + * Mail Client. This interface can also be used to get/set the user preference + * for the default Mail Client. + * + */ +[scriptable, uuid(c5be14ba-4e0a-4eec-a1b8-04363761d63c)] +interface nsIMapiRegistry: nsISupports { + + /** This is set to TRUE if Mozilla is the default Application + */ + attribute boolean isDefaultMailClient; + + /** This is set TRUE only once per session. + */ + readonly attribute boolean showDialog; + + /** This will bring the dialog asking the user if he/she wants to set + * Mozilla as default Mail Client. + * Call this only if Mozilla is not the default Mail client + */ + void showMailIntegrationDialog(in nsIDOMWindow parentWindow); + +}; + +%{C++ +#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1" +#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry" +%} diff --git a/mailnews/mapi/mapihook/public/nsIMapiSupport.idl b/mailnews/mapi/mapihook/public/nsIMapiSupport.idl new file mode 100644 index 00000000000..2777e3afc18 --- /dev/null +++ b/mailnews/mapi/mapihook/public/nsIMapiSupport.idl @@ -0,0 +1,64 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +/** + * This interface provides support for registering Mozilla as a COM component + * for extending the use of Mail/News through Simple MAPI. + * + */ + +[noscript, uuid(8967fed2-c8bb-11d5-a3e9-00b0d0f3baa7)] +interface nsIMapiSupport : nsISupports { + + /** Initiates MAPI support + */ + + void initializeMAPISupport(); + + /** Shuts down the MAPI support + */ + + void shutdownMAPISupport(); +}; + +%{C++ +#define NS_IMAPISUPPORT_CONTRACTID "@mozilla.org/mapisupport;1" +#define NS_IMAPISUPPORT_CLASSNAME "Mozilla MAPI Support" +%} + + diff --git a/mailnews/mapi/mapihook/src/Registry.cpp b/mailnews/mapi/mapihook/src/Registry.cpp new file mode 100644 index 00000000000..2a985f8ce78 --- /dev/null +++ b/mailnews/mapi/mapihook/src/Registry.cpp @@ -0,0 +1,323 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#undef _UNICODE +#undef UNICODE + +#include +#include "nsString.h" +#include "Registry.h" + +#define MAPI_PROXY_DLL_NAME "MapiProxy.dll" +#define MAPI_STARTUP_ARG " /MAPIStartUp" +#define MAX_SIZE 2048 + +// Size of a CLSID as a string +const int CLSID_STRING_SIZE = 39; + +// Proxy/Stub Dll Routines + +typedef HRESULT (__stdcall ProxyServer)(); + + +// Convert a CLSID to a char string. + +BOOL CLSIDtochar(const CLSID& clsid, char* szCLSID, + int length) +{ + LPOLESTR wszCLSID = NULL; + + // Get CLSID + HRESULT hr = StringFromCLSID(clsid, &wszCLSID); + if (FAILED(hr)) + return FALSE; + + // Covert from wide characters to non-wide. + wcstombs(szCLSID, wszCLSID, length); + + // Free memory. + CoTaskMemFree(wszCLSID); + + return TRUE; +} + +// Create a key and set its value. + +BOOL setKeyAndValue(nsCAutoString keyName, const char* subKey, + const char* theValue) +{ + HKEY hKey; + BOOL retValue = TRUE; + + nsCAutoString theKey(keyName); + if (subKey != NULL) + { + theKey += "\\"; + theKey += subKey; + } + + // Create and open key and subkey. + long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, theKey.get(), + 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hKey, NULL); + if (lResult != ERROR_SUCCESS) + return FALSE ; + + // Set the Value. + if (theValue != NULL) + { + lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)theValue, + strlen(theValue)+1); + if (lResult != ERROR_SUCCESS) + retValue = FALSE; + } + + RegCloseKey(hKey); + return TRUE; +} + +// Delete a key and all of its descendents. + +LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete + const char* lpszKeyChild) // Key to delete +{ + // Open the child. + HKEY hKeyChild ; + LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0, + KEY_ALL_ACCESS, &hKeyChild) ; + if (lRes != ERROR_SUCCESS) + { + return lRes ; + } + + // Enumerate all of the decendents of this child. + FILETIME time ; + char szBuffer[MAX_SIZE] ; + DWORD dwSize = MAX_SIZE ; + while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, + NULL, NULL, &time) == S_OK) + { + // Delete the decendents of this child. + lRes = recursiveDeleteKey(hKeyChild, szBuffer) ; + if (lRes != ERROR_SUCCESS) + { + // Cleanup before exiting. + RegCloseKey(hKeyChild) ; + return lRes; + } + dwSize = MAX_SIZE; + } + + // Close the child. + RegCloseKey(hKeyChild) ; + + // Delete this child. + return RegDeleteKey(hKeyParent, lpszKeyChild) ; +} + +void RegisterProxy() +{ + HINSTANCE h = NULL; + ProxyServer *RegisterFunc = NULL; + + char szModule[MAX_SIZE]; + char *pTemp = NULL; + + HMODULE hModule = GetModuleHandle(NULL); + DWORD dwResult = ::GetModuleFileName(hModule, szModule, + sizeof(szModule)/sizeof(char)); + if (dwResult == 0) + return; + + pTemp = strrchr(szModule, '\\'); + if (pTemp == NULL) + return; + + *pTemp = '\0'; + nsCAutoString proxyPath(szModule); + + proxyPath += "\\"; + proxyPath += MAPI_PROXY_DLL_NAME; + + h = LoadLibrary(proxyPath.get()); + if (h == NULL) + return; + + RegisterFunc = (ProxyServer *) GetProcAddress(h, "DllRegisterServer"); + if (RegisterFunc) + RegisterFunc(); + + FreeLibrary(h); +} + +void UnRegisterProxy() +{ + HINSTANCE h = NULL; + ProxyServer *UnRegisterFunc = NULL; + + char szModule[MAX_SIZE]; + char *pTemp = NULL; + + HMODULE hModule = GetModuleHandle(NULL); + DWORD dwResult = ::GetModuleFileName(hModule, szModule, + sizeof(szModule)/sizeof(char)); + if (dwResult == 0) + return; + + pTemp = strrchr(szModule, '\\'); + if (pTemp == NULL) + return; + + *pTemp = '\0'; + nsCAutoString proxyPath(szModule); + + proxyPath += "\\"; + proxyPath += MAPI_PROXY_DLL_NAME; + + h = LoadLibrary(proxyPath.get()); + if (h == NULL) + return; + + UnRegisterFunc = (ProxyServer *) GetProcAddress(h, "DllUnregisterServer"); + if (UnRegisterFunc) + UnRegisterFunc(); + + FreeLibrary(h); +} + +// Register the component in the registry. + +HRESULT RegisterServer(const CLSID& clsid, // Class ID + const char* szFriendlyName, // Friendly Name + const char* szVerIndProgID, // Programmatic + const char* szProgID) // IDs +{ + HMODULE hModule = GetModuleHandle(NULL); + char szModuleName[MAX_SIZE]; + char szCLSID[CLSID_STRING_SIZE]; + + nsCAutoString independentProgId(szVerIndProgID); + nsCAutoString progId(szProgID); + + DWORD dwResult = ::GetModuleFileName(hModule, szModuleName, + sizeof(szModuleName)/sizeof(char)); + + if (dwResult == 0) + return S_FALSE; + + nsCAutoString moduleName(szModuleName); + nsCAutoString registryKey("CLSID\\"); + + moduleName += MAPI_STARTUP_ARG; + + // Convert the CLSID into a char. + + if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID))) + return S_FALSE; + registryKey += szCLSID; + + // Add the CLSID to the registry. + if (!setKeyAndValue(registryKey, NULL, szFriendlyName)) + return S_FALSE; + + if (!setKeyAndValue(registryKey, "LocalServer32", moduleName.get())) + return S_FALSE; + + // Add the ProgID subkey under the CLSID key. + if (!setKeyAndValue(registryKey, "ProgID", szProgID)) + return S_FALSE; + + // Add the version-independent ProgID subkey under CLSID key. + if (!setKeyAndValue(registryKey, "VersionIndependentProgID", szVerIndProgID)) + return S_FALSE; + + // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT. + if (!setKeyAndValue(independentProgId, NULL, szFriendlyName)) + return S_FALSE; + if (!setKeyAndValue(independentProgId, "CLSID", szCLSID)) + return S_FALSE; + if (!setKeyAndValue(independentProgId, "CurVer", szProgID)) + return S_FALSE; + + // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT. + if (!setKeyAndValue(progId, NULL, szFriendlyName)) + return S_FALSE; + if (!setKeyAndValue(progId, "CLSID", szCLSID)) + return S_FALSE; + + RegisterProxy(); + + return S_OK; +} + +LONG UnregisterServer(const CLSID& clsid, // Class ID + const char* szVerIndProgID, // Programmatic + const char* szProgID) // IDs +{ + LONG lResult = S_OK; + + // Convert the CLSID into a char. + + char szCLSID[CLSID_STRING_SIZE]; + if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID))) + return S_FALSE; + + UnRegisterProxy(); + + nsCAutoString registryKey("CLSID\\"); + registryKey += szCLSID; + + lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get()); + if (lResult == ERROR_SUCCESS || lResult == ERROR_FILE_NOT_FOUND) + return lResult; + + registryKey += "\\LocalServer32"; + + // Delete only the path for this server. + + lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get()); + if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND) + return lResult; + + // Delete the version-independent ProgID Key. + lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID); + if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND) + return lResult; + + lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID); + + return lResult; +} diff --git a/mailnews/mapi/mapihook/src/Registry.h b/mailnews/mapi/mapihook/src/Registry.h new file mode 100644 index 00000000000..3d6ba788892 --- /dev/null +++ b/mailnews/mapi/mapihook/src/Registry.h @@ -0,0 +1,56 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Krishna Mohan Khandrika + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _REGISTRY_H_ +#define _REGISTRY_H_ + +#include + +// This function will register a component in the Registry. + +HRESULT RegisterServer(const CLSID& clsid, + const char* szFriendlyName, + const char* szVerIndProgID, + const char* szProgID) ; + +// This function will unregister a component. + +HRESULT UnregisterServer(const CLSID& clsid, + const char* szVerIndProgID, + const char* szProgID) ; + +#endif diff --git a/mailnews/mapi/mapihook/src/makefile.win b/mailnews/mapi/mapihook/src/makefile.win new file mode 100644 index 00000000000..d0183e183ce --- /dev/null +++ b/mailnews/mapi/mapihook/src/makefile.win @@ -0,0 +1,107 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Srilatha Moturi +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH=..\..\..\.. + +MODULE = msgMapi +MAKE_OBJ_TYPE = DLL +LIBRARY_NAME=$(MODULE) +MODULE_NAME = $(MODULE) + +REQUIRES = xpcom \ + string \ + MapiProxy \ + appshell \ + windowwatcher \ + dom \ + profile \ + msgbase \ + pref \ + msgbaseutil \ + msgcompo \ + mailnews \ + necko \ + intl \ + editor \ + msgdb \ + uriloader \ + appstartup \ + $(NULL) + +include <$(DEPTH)\config\config.mak> +############################################################################ + +LCFLAGS=-DUNICODE -D_UNICODE + + + +OBJS= \ + ..\build\$(OBJDIR)\msgMapi_i.obj \ + .\$(OBJDIR)\msgMapiFactory.obj \ + .\$(OBJDIR)\msgMapiHook.obj \ + .\$(OBJDIR)\msgMapiImp.obj \ + .\$(OBJDIR)\msgMapiMain.obj \ + .\$(OBJDIR)\msgMapiSupport.obj \ + .\$(OBJDIR)\nsMapiRegistry.obj \ + .\$(OBJDIR)\nsMapiRegistryUtils.obj \ + .\$(OBJDIR)\Registry.obj \ + $(NULL) + + + +LLIBS= \ + $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\msgbsutl.lib \ + $(LIBNSPR) \ + $(NULL) + +WIN_LIBS= \ + ole32.lib \ + $(NULL) + +EXPORTS= \ + msgMapiFactory.h \ + msgMapiHook.h \ + msgMapiImp.h \ + msgMapiMain.h \ + msgMapiSupport.h \ + nsMapiRegistry.h \ + nsMapiRegistryUtils.h \ + Registry.h \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> diff --git a/mailnews/mapi/mapihook/src/msgMapiFactory.cpp b/mailnews/mapi/mapihook/src/msgMapiFactory.cpp new file mode 100644 index 00000000000..803fb8d6068 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiFactory.cpp @@ -0,0 +1,118 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#undef UNICODE +#undef _UNICODE + +#include "msgMapiFactory.h" +#include "msgMapiImp.h" +#include "msgMapi.h" + +CMapiFactory ::CMapiFactory() +: m_cRef(1) +{ +} + +CMapiFactory::~CMapiFactory() +{ +} + +STDMETHODIMP CMapiFactory::QueryInterface(const IID& aIid, void** aPpv) +{ + if ((aIid == IID_IUnknown) || (aIid == IID_IClassFactory)) + { + *aPpv = static_cast(this); + } + else + { + *aPpv = nsnull; + return E_NOINTERFACE; + } + reinterpret_cast(*aPpv)->AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CMapiFactory::AddRef() +{ + return (PR_AtomicIncrement(&m_cRef)); +} + +STDMETHODIMP_(ULONG) CMapiFactory::Release() +{ + PRInt32 temp; + temp = PR_AtomicDecrement(&m_cRef); + if (m_cRef == 0) + { + delete this; + return 0; + } + + return temp; +} + +STDMETHODIMP CMapiFactory::CreateInstance(IUnknown* aUnknownOuter, + const IID& aIid, + void** aPpv) +{ + // Cannot aggregate. + + if (aUnknownOuter != nsnull) + { + return CLASS_E_NOAGGREGATION ; + } + + // Create component. + + CMapiImp* pImp = new CMapiImp(); + if (pImp == nsnull) + { + return E_OUTOFMEMORY ; + } + + // Get the requested interface. + HRESULT hr = pImp->QueryInterface(aIid, aPpv); + + // Release the IUnknown pointer. + // (If QueryInterface failed, component will delete itself.) + + pImp->Release(); + return hr; +} + +STDMETHODIMP CMapiFactory::LockServer(PRBool aLock) +{ + return S_OK ; +} diff --git a/mailnews/mapi/mapihook/src/msgMapiFactory.h b/mailnews/mapi/mapihook/src/msgMapiFactory.h new file mode 100644 index 00000000000..c09d34d0290 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiFactory.h @@ -0,0 +1,69 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef MSG_MAPI_FACTORY_H +#define MSG_MAPI_FACTORY_H + +#include +#include +#include "nspr.h" + + +class CMapiFactory : public IClassFactory +{ +public : + + // IUnknown + + STDMETHODIMP QueryInterface (REFIID aIid, void** aPpv); + STDMETHODIMP_(ULONG) AddRef(void); + STDMETHODIMP_(ULONG) Release(void); + + // IClassFactory + + STDMETHODIMP CreateInstance (LPUNKNOWN aUnkOuter, REFIID aIid, void **aPpv); + STDMETHODIMP LockServer (BOOL aLock); + + CMapiFactory (); + ~CMapiFactory (); + +private : + + PRInt32 m_cRef; +}; + +#endif // MSG_MAPI_FACTORY_H + diff --git a/mailnews/mapi/mapihook/src/msgMapiHook.cpp b/mailnews/mapi/mapihook/src/msgMapiHook.cpp new file mode 100644 index 00000000000..a29ec795ce8 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiHook.cpp @@ -0,0 +1,787 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * Contributor(s): Srilatha Moturi (srilatha@netscape.com) + * Contributor(s): Rajiv Dayal (rdayal@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#define MAPI_STARTUP_ARG "/MAPIStartUp" + +#define MAPI_STARTUP_ARG "/MAPIStartUp" + +#include +#include +#include + +#include "nsCOMPtr.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsISupports.h" +#include "nsIPromptService.h" +#include "nsAppShellCIDs.h" +#include "nsIDOMWindowInternal.h" +#include "nsIAppShellService.h" +#include "nsINativeAppSupport.h" +#include "nsICmdLineService.h" +#include "nsIProfileInternal.h" +#include "nsIMsgAccountManager.h" +#include "nsIDOMWindowInternal.h" +#include "nsXPIDLString.h" +#include "nsReadableUtils.h" +#include "nsMsgBaseCID.h" +#include "nsIStringBundle.h" +#include "nsIPref.h" +#include "nsString.h" + +#include "nsIMsgAttachment.h" +#include "nsIMsgCompFields.h" +#include "nsIMsgComposeParams.h" +#include "nsIMsgCompose.h" +#include "nsMsgCompCID.h" +#include "nsIMsgSend.h" +#include "nsIProxyObjectManager.h" +#include "nsIMsgComposeService.h" +#include "nsProxiedService.h" +#include "nsSpecialSystemDirectory.h" +#include "nsMsgI18N.h" + +#include "msgMapi.h" +#include "msgMapiHook.h" +#include "msgMapiSupport.h" +#include "msgMapiMain.h" +#include "nsNetUtil.h" + +static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID); + +class nsMAPISendListener : public nsIMsgSendListener +{ +public: + + virtual ~nsMAPISendListener() { } + + // nsISupports interface + NS_DECL_ISUPPORTS + + /* void OnStartSending (in string aMsgID, in PRUint32 aMsgSize); */ + NS_IMETHOD OnStartSending(const char *aMsgID, PRUint32 aMsgSize) { return NS_OK; } + + /* void OnProgress (in string aMsgID, in PRUint32 aProgress, in PRUint32 aProgressMax); */ + NS_IMETHOD OnProgress(const char *aMsgID, PRUint32 aProgress, PRUint32 aProgressMax) { return NS_OK;} + + /* void OnStatus (in string aMsgID, in wstring aMsg); */ + NS_IMETHOD OnStatus(const char *aMsgID, const PRUnichar *aMsg) { return NS_OK;} + + /* void OnStopSending (in string aMsgID, in nsresult aStatus, in wstring aMsg, in nsIFileSpec returnFileSpec); */ + NS_IMETHOD OnStopSending(const char *aMsgID, nsresult aStatus, const PRUnichar *aMsg, + nsIFileSpec *returnFileSpec) { + m_done = PR_TRUE; + HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, (LPCTSTR) MAPI_SENDCOMPLETE_EVENT) ; + SetEvent (hEvent) ; + CloseHandle (hEvent) ; + return NS_OK ; + } + + /* void OnSendNotPerformed */ + NS_IMETHOD OnSendNotPerformed(const char *aMsgID, nsresult aStatus) + { + return OnStopSending(aMsgID, aStatus, nsnull, nsnull) ; + } + + /* void OnGetDraftFolderURI (); */ + NS_IMETHOD OnGetDraftFolderURI(const char *aFolderURI) {return NS_OK;} + + static nsresult CreateMAPISendListener( nsIMsgSendListener **ppListener); + + PRBool IsDone() { return m_done ; } + +protected : + nsMAPISendListener() { + NS_INIT_REFCNT(); + m_done = PR_FALSE; + } + + PRBool m_done; +}; + + +NS_IMPL_THREADSAFE_ISUPPORTS1(nsMAPISendListener, nsIMsgSendListener) + +nsresult nsMAPISendListener::CreateMAPISendListener( nsIMsgSendListener **ppListener) +{ + NS_ENSURE_ARG_POINTER(ppListener) ; + + *ppListener = new nsMAPISendListener(); + if (! *ppListener) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*ppListener); + return NS_OK; +} + +PRBool nsMapiHook::isMapiService = PR_FALSE; + +PRBool nsMapiHook::Initialize() +{ + nsresult rv; + nsCOMPtr native; + + nsCOMPtr cmdLineArgs(do_GetService(kCmdLineServiceCID, &rv)); + if (NS_FAILED(rv)) return PR_FALSE; + + nsCOMPtr appShell (do_GetService( "@mozilla.org/appshell/appShellService;1", &rv)); + if (NS_FAILED(rv)) return PR_FALSE; + + rv = appShell->GetNativeAppSupport( getter_AddRefs( native )); + if (NS_FAILED(rv)) return PR_FALSE; + + rv = native->EnsureProfile(cmdLineArgs); + if (NS_FAILED(rv)) return PR_FALSE; + + return PR_TRUE; +} + +void nsMapiHook::CleanUp() +{ + // This routine will be fully implemented in future + // to cleanup mapi related stuff inside mozilla code. +} + +PRBool nsMapiHook::DisplayLoginDialog(PRBool aLogin, PRUnichar **aUsername, \ + PRUnichar **aPassword) +{ + nsresult rv; + PRBool btnResult = PR_FALSE; + + nsCOMPtr appShell(do_GetService( "@mozilla.org/appshell/appShellService;1", &rv)); + if (NS_FAILED(rv) || !appShell) return PR_FALSE; + + nsCOMPtr dlgService(do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv)); + if (NS_SUCCEEDED(rv) && dlgService) + { + nsCOMPtr bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv)); + if (NS_FAILED(rv) || !bundleService) return PR_FALSE; + + nsCOMPtr bundle; + rv = bundleService->CreateBundle(MAPI_PROPERTIES_CHROME, getter_AddRefs(bundle)); + if (NS_FAILED(rv) || !bundle) return PR_FALSE; + + nsCOMPtr brandBundle; + rv = bundleService->CreateBundle( + "chrome://global/locale/brand.properties", + getter_AddRefs(brandBundle)); + if (NS_FAILED(rv)) return PR_FALSE; + + nsXPIDLString brandName; + rv = brandBundle->GetStringFromName( + NS_LITERAL_STRING("brandShortName").get(), + getter_Copies(brandName)); + if (NS_FAILED(rv)) return PR_FALSE; + + nsXPIDLString loginTitle; + const PRUnichar *brandStrings[] = { brandName.get() }; + NS_NAMED_LITERAL_STRING(loginTitlePropertyTag, "loginTitle"); + const PRUnichar *dTitlePropertyTag = loginTitlePropertyTag.get(); + rv = bundle->FormatStringFromName(dTitlePropertyTag, brandStrings, 1, + getter_Copies(loginTitle)); + if (NS_FAILED(rv)) return PR_FALSE; + + if (aLogin) + { + nsXPIDLString loginText; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("loginTextwithName").get(), + getter_Copies(loginText)); + if (NS_FAILED(rv) || !loginText) return PR_FALSE; + + rv = dlgService->PromptUsernameAndPassword(nsnull, loginTitle, + loginText, aUsername, aPassword, + nsnull, PR_FALSE, &btnResult); + } + else + { + //nsString loginString; + nsXPIDLString loginText; + const PRUnichar *userNameStrings[] = { *aUsername }; + + NS_NAMED_LITERAL_STRING(loginTextPropertyTag, "loginText"); + const PRUnichar *dpropertyTag = loginTextPropertyTag.get(); + rv = bundle->FormatStringFromName(dpropertyTag, userNameStrings, 1, + getter_Copies(loginText)); + if (NS_FAILED(rv)) return PR_FALSE; + + rv = dlgService->PromptPassword(nsnull, loginTitle, loginText, + aPassword, nsnull, PR_FALSE, &btnResult); + } + } + + return btnResult; +} + +PRBool nsMapiHook::VerifyUserName(const PRUnichar *aUsername, char **aIdKey) +{ + nsresult rv; + + if (aUsername == nsnull) + return PR_FALSE; + + nsCOMPtr accountManager(do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) return PR_FALSE; + nsCOMPtr identities; + rv = accountManager->GetAllIdentities(getter_AddRefs(identities)); + if (NS_FAILED(rv)) return PR_FALSE; + PRUint32 numIndentities; + identities->Count(&numIndentities); + + for (PRUint32 i = 0; i < numIndentities; i++) + { + // convert supports->Identity + nsCOMPtr thisSupports; + rv = identities->GetElementAt(i, getter_AddRefs(thisSupports)); + if (NS_FAILED(rv)) continue; + nsCOMPtr thisIdentity(do_QueryInterface(thisSupports, &rv)); + if (NS_SUCCEEDED(rv) && thisIdentity) + { + nsXPIDLCString email; + rv = thisIdentity->GetEmail(getter_Copies(email)); + if (NS_FAILED(rv)) continue; + + // get the username from the email and compare with the username + nsCAutoString aEmail(email.get()); + PRInt32 index = aEmail.FindChar('@'); + if (index != -1) + aEmail.Truncate(index); + + if (nsDependentString(aUsername) == NS_ConvertASCIItoUCS2(aEmail)) // == overloaded + return NS_SUCCEEDED(thisIdentity->GetKey(aIdKey)); + } + } + + return PR_FALSE; +} + +PRBool +nsMapiHook::IsBlindSendAllowed() +{ + PRBool enabled = PR_FALSE; + PRBool warn = PR_TRUE; + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID); + if (prefs) { + prefs->GetBoolPref(PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND,&warn); + prefs->GetBoolPref(PREF_MAPI_BLIND_SEND_ENABLED,&enabled); + } + if (!enabled) + return PR_FALSE; + + if (!warn) + return PR_TRUE; // Everything is okay. + + nsresult rv; + nsCOMPtr bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv)); + if (NS_FAILED(rv) || !bundleService) return PR_FALSE; + + nsCOMPtr bundle; + rv = bundleService->CreateBundle(MAPI_PROPERTIES_CHROME, getter_AddRefs(bundle)); + if (NS_FAILED(rv) || !bundle) return PR_FALSE; + + nsXPIDLString warningMsg; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("mapiBlindSendWarning").get(), + getter_Copies(warningMsg)); + if (NS_FAILED(rv)) return PR_FALSE; + + nsXPIDLString dontShowAgainMessage; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("mapiBlindSendDontShowAgain").get(), + getter_Copies(dontShowAgainMessage)); + if (NS_FAILED(rv)) return PR_FALSE; + + nsCOMPtr dlgService(do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv)); + if (NS_FAILED(rv) || !dlgService) return PR_FALSE; + + PRBool continueToWarn = PR_TRUE; + PRBool okayToContinue = PR_FALSE; + dlgService->ConfirmCheck(nsnull, nsnull, warningMsg, dontShowAgainMessage, &continueToWarn, &okayToContinue); + + if (!continueToWarn && okayToContinue && prefs) + prefs->SetBoolPref(PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND,PR_FALSE); + + return okayToContinue; + +} + +// this is used for Send without UI +nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields) +{ + nsresult rv = NS_OK ; + + if (!IsBlindSendAllowed()) + return NS_ERROR_FAILURE; + + /** create nsIMsgComposeParams obj and other fields to populate it **/ + + // get parent window + nsCOMPtr appService = do_GetService( "@mozilla.org/appshell/appShellService;1", &rv); + if (NS_FAILED(rv)|| (!appService) ) return rv ; + + nsCOMPtr hiddenWindow; + rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow)); + + if ( NS_FAILED(rv) ) return rv ; + + // smtp password and Logged in used IdKey from MapiConfig (session obj) + nsMAPIConfiguration * pMapiConfig = nsMAPIConfiguration::GetMAPIConfiguration() ; + if (!pMapiConfig) return NS_ERROR_FAILURE ; // get the singelton obj + PRUnichar * password = pMapiConfig->GetPassword(aSession) ; + // password + nsCAutoString smtpPassword ; + smtpPassword.AssignWithConversion (password) ; + // Id key + char * MsgIdKey = pMapiConfig->GetIdKey(aSession) ; + + // get the MsgIdentity for the above key using AccountManager + nsCOMPtr accountManager = do_GetService (NS_MSGACCOUNTMANAGER_CONTRACTID) ; + if (NS_FAILED(rv) || (!accountManager) ) return rv ; + + nsCOMPtr pMsgId ; + rv = accountManager->GetIdentity (MsgIdKey, getter_AddRefs(pMsgId)) ; + if (NS_FAILED(rv) ) return rv ; + + // create a send listener to get back the send status + nsCOMPtr sendListener ; + rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ; + if (NS_FAILED(rv) || (!sendListener) ) return rv; + + // create the compose params object + nsCOMPtr pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv)); + if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ; + + // populate the compose params + pMsgComposeParams->SetType(nsIMsgCompType::New); + pMsgComposeParams->SetFormat(nsIMsgCompFormat::Default); + pMsgComposeParams->SetIdentity(pMsgId); + pMsgComposeParams->SetComposeFields(aCompFields); + pMsgComposeParams->SetSendListener(sendListener) ; + pMsgComposeParams->SetSmtpPassword(smtpPassword.get()); + + // create the nsIMsgCompose object to send the object + nsCOMPtr pMsgCompose (do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv)); + if (NS_FAILED(rv) || (!pMsgCompose) ) return rv ; + + /** initialize nsIMsgCompose, Send the message, wait for send completion response **/ + + rv = pMsgCompose->Initialize(hiddenWindow, pMsgComposeParams) ; + if (NS_FAILED(rv)) return rv ; + + pMsgCompose->SendMsg(nsIMsgSend::nsMsgDeliverNow, pMsgId, nsnull) ; + if (NS_FAILED(rv)) return rv ; + + // assign to interface pointer from nsCOMPtr to facilitate typecast below + nsIMsgSendListener * pSendListener = sendListener ; + + // we need to wait here to make sure that we return only after send is completed + // so we will have a event loop here which will process the events till the Send IsDone. + nsCOMPtr pEventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); + nsCOMPtr eventQueue; + pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,getter_AddRefs(eventQueue)); + while ( !((nsMAPISendListener *) pSendListener)->IsDone() ) + eventQueue->ProcessPendingEvents(); + + return rv ; +} + +// this is used to populate comp fields with Unicode data +nsresult nsMapiHook::PopulateCompFields(lpnsMapiMessage aMessage, + nsIMsgCompFields * aCompFields) +{ + nsresult rv = NS_OK ; + + if (aMessage->lpOriginator) + { + PRUnichar * From = aMessage->lpOriginator->lpszAddress ; + aCompFields->SetFrom (From) ; + } + + nsAutoString To ; + nsAutoString Cc ; + nsAutoString Bcc ; + + nsAutoString Comma ; + Comma.AssignWithConversion(","); + + if (aMessage->lpRecips) + { + for (int i=0 ; i < (int) aMessage->nRecipCount ; i++) + { + if (aMessage->lpRecips[i].lpszAddress) + { + switch (aMessage->lpRecips[i].ulRecipClass) + { + case MAPI_TO : + if (To.Length() > 0) + To += Comma ; + To += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ; + break ; + + case MAPI_CC : + if (Cc.Length() > 0) + Cc += Comma ; + Cc += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ; + break ; + + case MAPI_BCC : + if (Bcc.Length() > 0) + Bcc += Comma ; + Bcc += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ; + break ; + } + } + } + } + + // set To, Cc, Bcc + aCompFields->SetTo (To.get()) ; + aCompFields->SetCc (Cc.get()) ; + aCompFields->SetBcc (Bcc.get()) ; + + // set subject + if (aMessage->lpszSubject) + { + PRUnichar * Subject = aMessage->lpszSubject ; + aCompFields->SetSubject(Subject) ; + } + + // handle attachments as File URL + rv = HandleAttachments (aCompFields, aMessage->nFileCount, aMessage->lpFiles, PR_TRUE) ; + if (NS_FAILED(rv)) return rv ; + + // set body + if (aMessage->lpszNoteText) + { + PRUnichar * Body = aMessage->lpszNoteText ; + rv = aCompFields->SetBody(Body) ; + } + +#ifdef RAJIV_DEBUG + // testing what all was set in CompFields + printf ("To : %S \n", To.get()) ; + printf ("CC : %S \n", Cc.get() ) ; + printf ("BCC : %S \n", Bcc.get() ) ; +#endif + + return rv ; + +} + +nsresult nsMapiHook::HandleAttachments (nsIMsgCompFields * aCompFields, PRInt32 aFileCount, + lpnsMapiFileDesc aFiles, BOOL aIsUnicode) +{ + nsresult rv = NS_OK ; + + nsCAutoString Attachments ; + nsCAutoString TempFiles ; + + nsCOMPtr pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ; + if (NS_FAILED(rv) || (!pFile) ) return rv ; + + for (int i=0 ; i < aFileCount ; i++) + { + if (aFiles[i].lpszPathName) + { + // check if attachment exists + if (aIsUnicode) + pFile->InitWithUnicodePath (aFiles[i].lpszPathName) ; + else + pFile->InitWithPath ((char *) aFiles[i].lpszPathName) ; + PRBool bExist ; + rv = pFile->Exists(&bExist) ; + if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ; + + // create Msg attachment object + nsCOMPtr attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv); + if (NS_FAILED(rv) || (!attachment) ) return rv ; + + // set url + nsXPIDLCString pURL ; +#if 1 + pFile->GetURL (getter_Copies(pURL)) ; +#else + NS_GetURLFromFile(pFile, getter_Copies(pURL)); +#endif + attachment->SetUrl(pURL) ; + + if (aFiles[i].lpszFileName) + { + if (! aIsUnicode) + { + nsAutoString realFileName ; + realFileName.AssignWithConversion ((char *) aFiles[i].lpszFileName) ; + attachment->SetName(realFileName.get()) ; + // attachment->SetName( (nsDependentString(aFiles[i].lpszFileName)).get() ); + } + else + attachment->SetName(aFiles[i].lpszFileName) ; + } + + attachment->SetTemporary(PR_FALSE) ; + + rv = aCompFields->AddAttachment (attachment); + } + } + return rv ; +} + + +// this is used to convert non Unicode data and then populate comp fields +nsresult nsMapiHook::PopulateCompFieldsWithConversion(lpnsMapiMessage aMessage, + nsIMsgCompFields * aCompFields) +{ + nsresult rv = NS_OK ; + + if (aMessage->lpOriginator) + { + nsAutoString From ; + From.AssignWithConversion((char *) aMessage->lpOriginator->lpszAddress); + aCompFields->SetFrom (From.get()) ; + } + + nsAutoString To ; + nsAutoString Cc ; + nsAutoString Bcc ; + + nsAutoString Comma ; + Comma.AssignWithConversion(","); + + if (aMessage->lpRecips) + { + for (int i=0 ; i < (int) aMessage->nRecipCount ; i++) + { + if (aMessage->lpRecips[i].lpszAddress) + { + switch (aMessage->lpRecips[i].ulRecipClass) + { + case MAPI_TO : + if (To.Length() > 0) + To += Comma ; + To.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress); + break ; + + case MAPI_CC : + if (Cc.Length() > 0) + Cc += Comma ; + Cc.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress); + break ; + + case MAPI_BCC : + if (Bcc.Length() > 0) + Bcc += Comma ; + Bcc.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress) ; + break ; + } + } + } + } + + // set To, Cc, Bcc + aCompFields->SetTo (To.get()) ; + aCompFields->SetCc (Cc.get()) ; + aCompFields->SetBcc (Bcc.get()) ; + + nsCAutoString platformCharSet; + // set subject + if (aMessage->lpszSubject) + { + nsAutoString Subject ; + if (platformCharSet.IsEmpty()) + platformCharSet.Assign(nsMsgI18NFileSystemCharset()); + rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszSubject, Subject); + if (NS_FAILED(rv)) return rv ; + aCompFields->SetSubject(Subject.get()) ; + } + + // handle attachments as File URL + rv = HandleAttachments (aCompFields, aMessage->nFileCount, aMessage->lpFiles, PR_FALSE) ; + if (NS_FAILED(rv)) return rv ; + + // set body + if (aMessage->lpszNoteText) + { + nsAutoString Body ; + if (platformCharSet.IsEmpty()) + platformCharSet.Assign(nsMsgI18NFileSystemCharset()); + rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszNoteText, Body); + if (NS_FAILED(rv)) return rv ; + rv = aCompFields->SetBody(Body.get()) ; + } + +#ifdef RAJIV_DEBUG + // testing what all was set in CompFields + printf ("To : %S \n", To.get()) ; + printf ("CC : %S \n", Cc.get() ) ; + printf ("BCC : %S \n", Bcc.get() ) ; +#endif + + return rv ; +} + +// this is used to populate the docs as attachments in the Comp fields for Send Documents +nsresult nsMapiHook::PopulateCompFieldsForSendDocs(nsIMsgCompFields * aCompFields, ULONG aFlags, + PRUnichar * aDelimChar, PRUnichar * aFilePaths) +{ + nsAutoString strDelimChars ; + nsString strFilePaths; + nsresult rv = NS_OK ; + + if (aFlags & MAPI_UNICODE) + { + if (aDelimChar) + strDelimChars.Assign (aDelimChar) ; + if (aFilePaths) + strFilePaths.Assign (aFilePaths) ; + } + else + { + if (aDelimChar) + strDelimChars.AssignWithConversion ((char*) aDelimChar) ; + if (aFilePaths) + strFilePaths.AssignWithConversion ((char *) aFilePaths) ; + } + + // check for comma in filename + if (strDelimChars.Find (",") == kNotFound) // if comma is not in the delimiter specified by user + { + if (strFilePaths.Find(",") != kNotFound) // if comma found in filenames return error + return NS_ERROR_FILE_INVALID_PATH ; + } + + nsCString Attachments ; + + // only 1 file is to be sent, no delim specified + if ((!strDelimChars.Length()) && (strFilePaths.Length()>0)) + { + nsCOMPtr pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ; + if (NS_FAILED(rv) || (!pFile) ) return rv ; + pFile->InitWithUnicodePath (strFilePaths.get()) ; + + PRBool bExist ; + rv = pFile->Exists(&bExist) ; + if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ; + + nsXPIDLCString pURL ; +#if 1 + pFile->GetURL (getter_Copies(pURL)) ; +#else + NS_GetURLFromFile(pFile, getter_Copies(pURL)); +#endif + if (pURL) + Attachments.Assign(pURL) ; + + // set attachments for comp field and return + rv = aCompFields->SetAttachments (Attachments.get()); + return rv ; + } + + // multiple files to be sent, delim specified + nsCOMPtr pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ; + if (NS_FAILED(rv) || (!pFile) ) return rv ; + PRInt32 offset = 0 ; + PRInt32 FilePathsLen = strFilePaths.Length() ; + if (FilePathsLen) + { + PRUnichar * newFilePaths = (PRUnichar *) strFilePaths.get() ; + while (offset != kNotFound) + { + nsString RemainingPaths ; + RemainingPaths.Assign(newFilePaths) ; + offset = RemainingPaths.Find (strDelimChars) ; + if (offset != kNotFound) + { + RemainingPaths.SetLength (offset) ; + if ((offset + strDelimChars.Length()) < FilePathsLen) + newFilePaths += offset + strDelimChars.Length() ; + } + + pFile->InitWithUnicodePath (RemainingPaths.get()) ; + + #ifdef RAJIV_DEBUG + printf ("File : %S \n", RemainingPaths.get()) ; + #endif + PRBool bExist ; + rv = pFile->Exists(&bExist) ; + if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ; + + nsXPIDLCString pURL ; +#if 1 + pFile->GetURL (getter_Copies(pURL)) ; +#else + NS_GetURLFromFile(pFile, getter_Copies(pURL)); +#endif + if (pURL) + { + if (Attachments.Length() > 0) + Attachments.Append(",") ; + Attachments.Append(pURL) ; + } + } + rv = aCompFields->SetAttachments (Attachments.get()); + } + + return rv ; +} + +// this used for Send with UI +nsresult nsMapiHook::ShowComposerWindow (unsigned long aSession, nsIMsgCompFields * aCompFields) +{ + nsresult rv = NS_OK ; + + // create a send listener to get back the send status + nsCOMPtr sendListener ; + rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ; + if (NS_FAILED(rv) || (!sendListener) ) return rv ; + + // create the compose params object + nsCOMPtr pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv)); + if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ; + + // populate the compose params + pMsgComposeParams->SetType(nsIMsgCompType::New); + pMsgComposeParams->SetFormat(nsIMsgCompFormat::Default); + pMsgComposeParams->SetComposeFields(aCompFields); + pMsgComposeParams->SetSendListener(sendListener) ; + + /** get the nsIMsgComposeService object to open the compose window **/ + nsCOMPtr compService = do_GetService (NS_MSGCOMPOSESERVICE_CONTRACTID) ; + if (NS_FAILED(rv)|| (!compService) ) return rv ; + + rv = compService->OpenComposeWindowWithParams(nsnull, pMsgComposeParams) ; + if (NS_FAILED(rv)) return rv ; + + return rv ; +} diff --git a/mailnews/mapi/mapihook/src/msgMapiHook.h b/mailnews/mapi/mapihook/src/msgMapiHook.h new file mode 100644 index 00000000000..4802a761d3d --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiHook.h @@ -0,0 +1,66 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef MSG_MAPI_HOOK_H_ +#define MSG_MAPI_HOOK_H_ + +#include "prtypes.h" + +class nsMapiHook +{ + public : + + static PRBool Initialize(); + static PRBool DisplayLoginDialog(PRBool aLogin, PRUnichar **aUsername, + PRUnichar **aPassword); + static PRBool VerifyUserName(const PRUnichar *aUsername, char **aIdKey); + + static PRBool IsBlindSendAllowed () ; + static nsresult BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields) ; + static nsresult ShowComposerWindow (unsigned long aSession, nsIMsgCompFields * aCompFields) ; + static nsresult PopulateCompFields(lpnsMapiMessage aMessage, nsIMsgCompFields * aCompFields) ; + static nsresult PopulateCompFieldsWithConversion(lpnsMapiMessage aMessage, + nsIMsgCompFields * aCompFields) ; + static nsresult PopulateCompFieldsForSendDocs(nsIMsgCompFields * aCompFields, + ULONG aFlags, LPTSTR aDelimChar, LPTSTR aFilePaths) ; + static nsresult HandleAttachments (nsIMsgCompFields * aCompFields, PRInt32 aFileCount, + lpnsMapiFileDesc aFiles, BOOL aIsUnicode) ; + static void CleanUp(); + + static PRBool isMapiService; +}; + +#endif // MSG_MAPI_HOOK_H_ diff --git a/mailnews/mapi/mapihook/src/msgMapiImp.cpp b/mailnews/mapi/mapihook/src/msgMapiImp.cpp new file mode 100644 index 00000000000..de25aed8d8d --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiImp.cpp @@ -0,0 +1,263 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * Contributor(s): Rajiv Dayal (rdayal@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include +#include "msgMapi.h" +#include "msgMapiImp.h" +#include "msgMapiFactory.h" +#include "msgMapiMain.h" + +#include "nsMsgCompFields.h" +#include "msgMapiHook.h" +#include "nsString.h" +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsMsgCompCID.h" + + + +CMapiImp::CMapiImp() +: m_cRef(1) +{ + m_Lock = PR_NewLock(); +} + +CMapiImp::~CMapiImp() +{ + if (m_Lock) + PR_DestroyLock(m_Lock); +} + +STDMETHODIMP CMapiImp::QueryInterface(const IID& aIid, void** aPpv) +{ + if (aIid == IID_IUnknown) + { + *aPpv = static_cast(this); + } + else if (aIid == IID_nsIMapi) + { + *aPpv = static_cast(this); + } + else + { + *aPpv = nsnull; + return E_NOINTERFACE; + } + + reinterpret_cast(*aPpv)->AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CMapiImp::AddRef() +{ + return PR_AtomicIncrement(&m_cRef); +} + +STDMETHODIMP_(ULONG) CMapiImp::Release() +{ + PRInt32 temp; + temp = PR_AtomicDecrement(&m_cRef); + if (m_cRef == 0) + { + delete this; + return 0; + } + + return temp; +} + +STDMETHODIMP CMapiImp::IsValid() +{ + return S_OK; +} + +STDMETHODIMP CMapiImp::IsValidSession(unsigned long aSession) +{ + nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration(); + if (pConfig && pConfig->IsSessionValid(aSession)) + return S_OK; + + return E_FAIL; +} + +STDMETHODIMP CMapiImp::Initialize() +{ + HRESULT hr = E_FAIL; + + if (!m_Lock) + return E_FAIL; + + PR_Lock(m_Lock); + + // Initialize MAPI Configuration + + nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration(); + if (pConfig != nsnull) + if (nsMapiHook::Initialize()) + hr = S_OK; + + PR_Unlock(m_Lock); + + return hr; +} + +STDMETHODIMP CMapiImp::Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin, LOGIN_PW_TYPE aPassWord, + unsigned long aFlags, unsigned long *aSessionId) +{ + HRESULT hr = E_FAIL; + PRBool bNewSession = PR_FALSE; + char *id_key = nsnull; + + if (aFlags & MAPI_NEW_SESSION) + bNewSession = PR_TRUE; + + // Check For Profile Name + if (aLogin != nsnull && aLogin[0] != '\0') + { + if (nsMapiHook::VerifyUserName(aLogin, &id_key) == PR_FALSE) + { + *aSessionId = MAPI_E_LOGIN_FAILURE; + return hr; + } + } + + // finally register(create) the session. + PRUint32 nSession_Id; + PRInt16 nResult = 0; + + nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration(); + if (pConfig != nsnull) + nResult = pConfig->RegisterSession(aUIArg, aLogin, aPassWord, + (aFlags & MAPI_FORCE_DOWNLOAD), bNewSession, + &nSession_Id, id_key); + switch (nResult) + { + case -1 : + { + *aSessionId = MAPI_E_TOO_MANY_SESSIONS; + return hr; + } + case 0 : + { + *aSessionId = MAPI_E_INSUFFICIENT_MEMORY; + return hr; + } + default : + { + *aSessionId = nSession_Id; + break; + } + } + + return S_OK; +} + +STDMETHODIMP CMapiImp::SendMail( unsigned long aSession, lpnsMapiMessage aMessage, + short aRecipCount, lpnsMapiRecipDesc aRecips , short aFileCount, lpnsMapiFileDesc aFiles , + unsigned long aFlags, unsigned long aReserved) +{ + nsresult rv = NS_OK ; + + // Assign the pointers in the aMessage struct to the array of Recips and Files + // recieved here from MS COM. These are used in BlindSendMail and ShowCompWin fns + aMessage->lpRecips = aRecips ; + aMessage->lpFiles = aFiles ; + + /** create nsIMsgCompFields obj and populate it **/ + nsCOMPtr pCompFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv) ; + if (NS_FAILED(rv) || (!pCompFields) ) return MAPI_E_INSUFFICIENT_MEMORY ; + + if (aFlags & MAPI_UNICODE) + rv = nsMapiHook::PopulateCompFields(aMessage, pCompFields) ; + else + rv = nsMapiHook::PopulateCompFieldsWithConversion(aMessage, pCompFields) ; + + if (NS_SUCCEEDED (rv)) + { + // see flag to see if UI needs to be brought up + if (!(aFlags & MAPI_DIALOG)) + { + rv = nsMapiHook::BlindSendMail(aSession, pCompFields); + } + else + { + rv = nsMapiHook::ShowComposerWindow(aSession, pCompFields); + } + } + + return nsMAPIConfiguration::GetMAPIErrorFromNSError (rv) ; +} + + +STDMETHODIMP CMapiImp::SendDocuments( unsigned long aSession, LPTSTR aDelimChar, + LPTSTR aFilePaths, LPTSTR aFileNames, ULONG aFlags) +{ + nsresult rv = NS_OK ; + + /** create nsIMsgCompFields obj and populate it **/ + nsCOMPtr pCompFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv) ; + if (NS_FAILED(rv) || (!pCompFields) ) return MAPI_E_INSUFFICIENT_MEMORY ; + + if (aFilePaths) + { + rv = nsMapiHook::PopulateCompFieldsForSendDocs(pCompFields, aFlags, aDelimChar, aFilePaths) ; + } + + if (NS_SUCCEEDED (rv)) + rv = nsMapiHook::ShowComposerWindow(aSession, pCompFields); + + return nsMAPIConfiguration::GetMAPIErrorFromNSError (rv) ; +} + +STDMETHODIMP CMapiImp::Logoff (unsigned long aSession) +{ + nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration(); + + if (pConfig->UnRegisterSession((PRUint32)aSession)) + return S_OK; + + return E_FAIL; +} + +STDMETHODIMP CMapiImp::CleanUp() +{ + nsMapiHook::CleanUp(); + return S_OK; +} + + diff --git a/mailnews/mapi/mapihook/src/msgMapiImp.h b/mailnews/mapi/mapihook/src/msgMapiImp.h new file mode 100644 index 00000000000..c823a8352ec --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiImp.h @@ -0,0 +1,92 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef MSG_MAPI_IMP_H +#define MSG_MAPI_IMP_H + +#include +#include +#include "msgMapi.h" +#include "nsXPIDLString.h" +#include "nspr.h" + +const CLSID CLSID_CMapiImp = {0x29f458be, 0x8866, 0x11d5, {0xa3, 0xdd, 0x0, 0xb0, 0xd0, 0xf3, 0xba, 0xa7}}; + +// this class implements the MS COM interface nsIMapi that provides the methods +// called by mapi32.dll to perform the mail operations as specified by MAPI. +// These class methods in turn use the Mozilla Mail XPCOM interfaces to do so. +class CMapiImp : public nsIMapi +{ + +public : + + // IUnknown + + STDMETHODIMP QueryInterface(const IID& aIid, void** aPpv); + STDMETHODIMP_(ULONG) AddRef(); + STDMETHODIMP_(ULONG) Release(); + + // Interface INsMapi + + STDMETHODIMP Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin, + LOGIN_PW_TYPE aPassWord, unsigned long aFlags, + unsigned long *aSessionId); + + STDMETHODIMP SendMail( unsigned long aSession, lpnsMapiMessage aMessage, + short aRecipCount, lpnsMapiRecipDesc aRecips , + short aFileCount, lpnsMapiFileDesc aFiles , + unsigned long aFlags, unsigned long aReserved) ; + + STDMETHODIMP SendDocuments( unsigned long aSession, LPTSTR aDelimChar, + LPTSTR aFilePaths, LPTSTR aFileNames, ULONG aFlags); + + STDMETHODIMP Initialize(); + STDMETHODIMP IsValid(); + STDMETHODIMP IsValidSession(unsigned long aSession); + + STDMETHODIMP Logoff (unsigned long aSession); + STDMETHODIMP CleanUp(); + + CMapiImp(); + ~CMapiImp(); + +private : + + PRLock *m_Lock; + PRInt32 m_cRef; +}; + +#endif // MSG_MAPI_IMP_H diff --git a/mailnews/mapi/mapihook/src/msgMapiMain.cpp b/mailnews/mapi/mapihook/src/msgMapiMain.cpp new file mode 100644 index 00000000000..1776e4fa002 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiMain.cpp @@ -0,0 +1,376 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include + +#include "msgCore.h" +#include "nsMsgComposeStringBundle.h" +#include "msgMapiMain.h" +#include "nsIServiceManager.h" +#include "nsCOMPtr.h" + +// move to xpcom bug 81956. +class nsPRUintKey : public nsHashKey { +protected: + PRUint32 mKey; +public: + nsPRUintKey(PRUint32 key) : mKey(key) {} + + PRUint32 HashCode(void) const { + return mKey; + } + + PRBool Equals(const nsHashKey *aKey) const { + return mKey == ((const nsPRUintKey *) aKey)->mKey; + } + nsHashKey *Clone() const { + return new nsPRUintKey(mKey); + } + PRUint32 GetValue() { return mKey; } +}; +// + + +nsMAPIConfiguration *nsMAPIConfiguration::m_pSelfRef = nsnull; +PRUint32 nsMAPIConfiguration::session_generator = 0; +PRUint32 nsMAPIConfiguration::sessionCount = 0; + +nsMAPIConfiguration *nsMAPIConfiguration::GetMAPIConfiguration() +{ + if (m_pSelfRef == nsnull) + m_pSelfRef = new nsMAPIConfiguration(); + + return m_pSelfRef; +} + +nsMAPIConfiguration::nsMAPIConfiguration() +: m_nMaxSessions(MAX_SESSIONS) +{ + m_Lock = PR_NewLock(); +} + +static PRBool +FreeSessionMapEntries(nsHashKey *aKey, void *aData, void* aClosure) +{ + nsMAPISession *pTemp = (nsMAPISession*) aData; + if (pTemp) + { + delete pTemp; + pTemp = nsnull; + } + return PR_TRUE; +} + +static PRBool +FreeProfileMapEntries(nsHashKey *aKey, void *aData, void* aClosure) +{ + return PR_TRUE; +} + +nsMAPIConfiguration::~nsMAPIConfiguration() +{ + if (m_Lock) + PR_DestroyLock(m_Lock); + + m_SessionMap.Reset(FreeSessionMapEntries); + m_ProfileMap.Reset(FreeProfileMapEntries); + } + +void nsMAPIConfiguration::OpenConfiguration() +{ + // No. of max. sessions is set to MAX_SESSIONS. In future + // if it is decided to have configuration (registry) + // parameter, this function can be used to set the + // max sessions; + + return; +} + +PRInt16 nsMAPIConfiguration::RegisterSession(PRUint32 aHwnd, + const PRUnichar *aUserName, const PRUnichar *aPassword, + PRBool aForceDownLoad, PRBool aNewSession, + PRUint32 *aSession, char *aIdKey) +{ + PRInt16 nResult = 0; + PRUint32 n_SessionId = 0; + + PR_Lock(m_Lock); + + // Check whether max sessions is exceeded + + if (sessionCount >= m_nMaxSessions) + { + PR_Unlock(m_Lock); + return -1; + } + + if (aUserName != nsnull && aUserName[0] != '\0') + { + nsStringKey usernameKey(aUserName); + n_SessionId = (PRUint32) m_ProfileMap.Get(&usernameKey); + } + + // try to share a session; if not create a session + + if (n_SessionId > 0) + { + nsPRUintKey sessionKey(n_SessionId); + nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey); + if (pTemp != nsnull) + { + pTemp->IncrementSession(); + *aSession = n_SessionId; + nResult = 1; + } + } + else if (aNewSession || n_SessionId == 0) // checking for n_SessionId is a concession + { + // create a new session ; if new session is specified OR there is no session + nsMAPISession *pTemp = nsnull; + pTemp = new nsMAPISession(aHwnd, aUserName, + aPassword, aForceDownLoad, aIdKey); + + if (pTemp != nsnull) + { + session_generator++; + + // I don't think there will be (2 power 32) sessions alive + // in a cycle. This is an assumption + + if (session_generator == 0) + session_generator++; + + nsPRUintKey sessionKey(session_generator); + m_SessionMap.Put(&sessionKey, pTemp); + if (aUserName != nsnull && aUserName[0] != '\0') + { + nsStringKey usernameKey(aUserName); + m_ProfileMap.Put(&usernameKey, (void*)session_generator); + } + + *aSession = session_generator; + sessionCount++; + nResult = 1; + } + } + + PR_Unlock(m_Lock); + return nResult; +} + +PRBool nsMAPIConfiguration::UnRegisterSession(PRUint32 aSessionID) +{ + PRBool bResult = PR_FALSE; + + PR_Lock(m_Lock); + + if (aSessionID != 0) + { + nsPRUintKey sessionKey(aSessionID); + nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey); + + if (pTemp != nsnull) + { + if (pTemp->DecrementSession() == 0) + { + if (pTemp->m_pProfileName.get() != nsnull) + { + nsStringKey stringKey(pTemp->m_pProfileName.get()); + m_ProfileMap.Remove(&stringKey); + } + m_SessionMap.Remove(&sessionKey); + sessionCount--; + bResult = PR_TRUE; + } + } + } + + PR_Unlock(m_Lock); + return bResult; +} + +PRBool nsMAPIConfiguration::IsSessionValid(PRUint32 aSessionID) +{ + if (aSessionID == 0) + return PR_FALSE; + + PRBool retValue = PR_FALSE; + nsPRUintKey sessionKey(aSessionID); + + PR_Lock(m_Lock); + + retValue = m_SessionMap.Exists(&sessionKey); + + PR_Unlock(m_Lock); + + return retValue; +} + + +PRUnichar *nsMAPIConfiguration::GetPassword(PRUint32 aSessionID) +{ + PRUnichar *pResult = nsnull; + + PR_Lock(m_Lock); + + if (aSessionID != 0) + { + nsPRUintKey sessionKey(aSessionID); + nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey); + + if (pTemp) + { + pResult = pTemp->GetPassword(); + } + } + + PR_Unlock(m_Lock); + + return pResult; +} + +char *nsMAPIConfiguration::GetIdKey(PRUint32 aSessionID) +{ + char *pResult = nsnull; + + PR_Lock(m_Lock); + + if (aSessionID != 0) + { + nsPRUintKey sessionKey(aSessionID); + nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey); + if (pTemp) + { + pResult = pTemp->GetIdKey(); + } + } + + PR_Unlock(m_Lock); + return pResult; +} + +// util func +HRESULT nsMAPIConfiguration::GetMAPIErrorFromNSError (nsresult res) +{ + HRESULT hr = SUCCESS_SUCCESS ; + + if (NS_SUCCEEDED (hr)) return hr ; + + // if failure return the related MAPI failure code + switch (res) + { + case NS_MSG_NO_RECIPIENTS : + hr = MAPI_E_BAD_RECIPTYPE ; + break ; + case NS_ERROR_COULD_NOT_GET_USERS_MAIL_ADDRESS : + hr = MAPI_E_INVALID_RECIPS ; + break ; + case NS_ERROR_COULD_NOT_LOGIN_TO_SMTP_SERVER : + hr = MAPI_E_LOGIN_FAILURE ; + break ; + case NS_MSG_UNABLE_TO_OPEN_FILE : + case NS_MSG_UNABLE_TO_OPEN_TMP_FILE : + case NS_MSG_COULDNT_OPEN_FCC_FOLDER : + case NS_ERROR_FILE_INVALID_PATH : + hr = MAPI_E_ATTACHMENT_OPEN_FAILURE ; + break ; + case NS_ERROR_FILE_TARGET_DOES_NOT_EXIST : + hr = MAPI_E_ATTACHMENT_NOT_FOUND ; + break ; + case NS_MSG_CANCELLING : + hr = MAPI_E_USER_ABORT ; + break ; + case NS_MSG_ERROR_WRITING_FILE : + case NS_MSG_UNABLE_TO_SAVE_TEMPLATE : + case NS_MSG_UNABLE_TO_SAVE_DRAFT : + hr = MAPI_E_ATTACHMENT_WRITE_FAILURE ; + break ; + default : + hr = MAPI_E_FAILURE ; + break ; + } + + return hr ; +} + + +nsMAPISession::nsMAPISession(PRUint32 aHwnd, const PRUnichar *aUserName,\ + const PRUnichar *aPassword, \ + PRBool aForceDownLoad, char *aKey) +: m_bIsForcedDownLoad(aForceDownLoad), + m_hAppHandle(aHwnd), + m_nShared(1), + m_pIdKey(aKey) +{ + m_pProfileName.Assign(aUserName); + m_pPassword.Assign(aPassword); +} + +nsMAPISession::~nsMAPISession() +{ + if (m_pIdKey != nsnull) + { + delete [] m_pIdKey; + m_pIdKey = nsnull; + } +} + +PRUint32 nsMAPISession::IncrementSession() +{ + return ++m_nShared; +} + +PRUint32 nsMAPISession::DecrementSession() +{ + return --m_nShared; +} + +PRUint32 nsMAPISession::GetSessionCount() +{ + return m_nShared; +} + +PRUnichar *nsMAPISession::GetPassword() +{ + return (PRUnichar *)m_pPassword.get(); +} + +char *nsMAPISession::GetIdKey() +{ + return m_pIdKey; +} + diff --git a/mailnews/mapi/mapihook/src/msgMapiMain.h b/mailnews/mapi/mapihook/src/msgMapiMain.h new file mode 100644 index 00000000000..aeff9f79b86 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiMain.h @@ -0,0 +1,112 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef MSG_MAPI_MAIN_H_ +#define NSG_MAPI_MAIN_H_ + +#define MAX_NAME_LEN 256 +#define MAX_PW_LEN 256 +#define MAX_SESSIONS 50 +#define MAPI_SENDCOMPLETE_EVENT "SendCompletionEvent" + +#define MAPI_PROPERTIES_CHROME "chrome://messenger-mapi/locale/mapi.properties" +#define PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND "mapi.blind-send.warn" +#define PREF_MAPI_BLIND_SEND_ENABLED "mapi.blind-send.enabled" + +#include "nsXPIDLString.h" +#include "nspr.h" +#include "nsString.h" +#include "nsHashtable.h" + +class nsMAPIConfiguration +{ +private : + + static PRUint32 session_generator; + static PRUint32 sessionCount; + static nsMAPIConfiguration *m_pSelfRef; + PRLock *m_Lock; + PRUint32 m_nMaxSessions; + + + nsHashtable m_ProfileMap; + nsHashtable m_SessionMap; + nsMAPIConfiguration(); + +public : + static nsMAPIConfiguration *GetMAPIConfiguration(); + void OpenConfiguration(); + PRInt16 RegisterSession(PRUint32 aHwnd, const PRUnichar *aUserName, \ + const PRUnichar *aPassword, PRBool aForceDownLoad, \ + PRBool aNewSession, PRUint32 *aSession, char *aIdKey); + PRBool IsSessionValid(PRUint32 aSessionID); + PRBool UnRegisterSession(PRUint32 aSessionID); + PRUnichar *GetPassword(PRUint32 aSessionID); + char *GetIdKey(PRUint32 aSessionID); + ~nsMAPIConfiguration(); + + // a util func + static HRESULT GetMAPIErrorFromNSError (nsresult res) ; +}; + +class nsMAPISession +{ + friend class nsMAPIConfiguration; + + private : + + PRBool m_bIsForcedDownLoad; + PRBool m_bApp_or_Service; + PRUint32 m_hAppHandle; + PRUint32 m_nShared; + char *m_pIdKey; + nsString m_pProfileName; + nsString m_pPassword; + + public : + + nsMAPISession(PRUint32 aHwnd, const PRUnichar *aUserName, \ + const PRUnichar *aPassword, \ + PRBool aForceDownLoad, char *aKey); + PRUint32 IncrementSession(); + PRUint32 DecrementSession(); + PRUint32 GetSessionCount(); + PRUnichar *nsMAPISession::GetPassword(); + char *nsMAPISession::GetIdKey(); + ~nsMAPISession(); +}; + +#endif // MSG_MAPI_MAIN_H_ diff --git a/mailnews/mapi/mapihook/src/msgMapiSupport.cpp b/mailnews/mapi/mapihook/src/msgMapiSupport.cpp new file mode 100644 index 00000000000..53090a035d9 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiSupport.cpp @@ -0,0 +1,209 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "nsCOMPtr.h" +#include "objbase.h" +#include "nsISupports.h" + +#include "nsIGenericFactory.h" +#include "nsIObserverService.h" +#include "nsIAppStartupNotifier.h" +#include "nsIServiceManager.h" +#include "nsIComponentManager.h" +#include "nsICategoryManager.h" + +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" +#include "nsIPrefBranchInternal.h" + +#include "msgMapiSupport.h" +#include "nsMapiRegistryUtils.h" +#include "nsMapiRegistry.h" +#include "msgMapiImp.h" + +/** Implementation of the nsIMapiSupport interface. + * Use standard implementation of nsISupports stuff. + */ + +NS_IMPL_THREADSAFE_ISUPPORTS2(nsMapiSupport, nsIMapiSupport, nsIObserver); + +static NS_METHOD nsMapiRegistrationProc(nsIComponentManager *aCompMgr, + nsIFile *aPath, const char *registryLocation, const char *componentType, + const nsModuleComponentInfo *info) +{ + + nsresult rv; + + nsCOMPtr categoryManager(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv)) + rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY, "Mapi Support", + "service," NS_IMAPISUPPORT_CONTRACTID, PR_TRUE, PR_TRUE, nsnull); + + return rv ; + +} + +NS_IMETHODIMP +nsMapiSupport::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) +{ + nsresult rv = NS_OK ; + + if (!nsCRT::strcmp(aTopic, "profile-after-change")) + return InitializeMAPISupport(); + + if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) + return ShutdownMAPISupport(); + + if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) + { + nsCOMPtr prefs = do_QueryInterface(aSubject, &rv); + if (NS_FAILED(rv)) return rv; + // which preference changed? + if (!nsCRT::strcmp(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, NS_ConvertUCS2toUTF8(aData).get())) + { + PRBool bIsDefault = PR_FALSE ; + rv = prefs->GetBoolPref(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, &bIsDefault); + if (NS_FAILED(rv)) return rv; + nsCOMPtr mapiRegistry = do_CreateInstance(NS_IMAPIREGISTRY_CONTRACTID, &rv) ; + if (NS_FAILED(rv)) return rv; + return mapiRegistry->SetIsDefaultMailClient(bIsDefault) ; + } + return rv ; + } + + nsCOMPtr observerService(do_GetService("@mozilla.org/observer-service;1", &rv)); + if (NS_FAILED(rv)) return rv; + + rv = observerService->AddObserver(this,"profile-after-change", PR_FALSE); + if (NS_FAILED(rv)) return rv; + + rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr prefInternal = do_QueryInterface(prefs, &rv); + if (NS_FAILED(rv)) return rv; + + rv = prefInternal->AddObserver(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, this, PR_FALSE); + if (NS_FAILED(rv)) return rv; + + return rv; +} + + +nsMapiSupport::nsMapiSupport() +: m_dwRegister(0), + m_nsMapiFactory(nsnull) +{ + NS_INIT_ISUPPORTS(); +} + +nsMapiSupport::~nsMapiSupport() +{ +} + +NS_IMETHODIMP +nsMapiSupport::InitializeMAPISupport() +{ + ::CoInitialize(nsnull) ; + + if (m_nsMapiFactory == nsnull) // No Registering if already done. Sanity Check!! + { + m_nsMapiFactory = new CMapiFactory(); + + if (m_nsMapiFactory != nsnull) + { + HRESULT hr = ::CoRegisterClassObject(CLSID_CMapiImp, \ + m_nsMapiFactory, \ + CLSCTX_LOCAL_SERVER, \ + REGCLS_MULTIPLEUSE, \ + &m_dwRegister); + + if (FAILED(hr)) + { + m_nsMapiFactory->Release() ; + m_nsMapiFactory = nsnull; + return NS_ERROR_FAILURE; + } + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsMapiSupport::ShutdownMAPISupport() +{ + if (m_dwRegister != 0) + ::CoRevokeClassObject(m_dwRegister); + + if (m_nsMapiFactory != nsnull) + { + m_nsMapiFactory->Release(); + m_nsMapiFactory = nsnull; + } + + ::CoUninitialize(); + + return NS_OK ; +} + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsMapiRegistry); +NS_GENERIC_FACTORY_CONSTRUCTOR(nsMapiSupport); + +// The list of components we register +static nsModuleComponentInfo components[] = +{ + { + NS_IMAPIREGISTRY_CLASSNAME, + NS_IMAPIREGISTRY_CID, + NS_IMAPIREGISTRY_CONTRACTID, + nsMapiRegistryConstructor + }, + +{ + NS_IMAPISUPPORT_CLASSNAME, + NS_IMAPISUPPORT_CID, + NS_IMAPISUPPORT_CONTRACTID, + nsMapiSupportConstructor, + nsMapiRegistrationProc, + nsnull +} +}; + +NS_IMPL_NSGETMODULE(msgMapiModule, components); + diff --git a/mailnews/mapi/mapihook/src/msgMapiSupport.h b/mailnews/mapi/mapihook/src/msgMapiSupport.h new file mode 100644 index 00000000000..a126fdd2e57 --- /dev/null +++ b/mailnews/mapi/mapihook/src/msgMapiSupport.h @@ -0,0 +1,66 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla + * + * The Initial Developer of the Original Code is + # Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef MSG_MAPI_SUPPORT_H_ +#define MSG_MAPI_SUPPORT_H_ + +#include "nsIObserver.h" +#include "nsIMapiSupport.h" +#include "msgMapiFactory.h" + +#define NS_IMAPISUPPORT_CID \ + {0x8967fed2, 0xc8bb, 0x11d5, \ + { 0xa3, 0xe9, 0x00, 0xb0, 0xd0, 0xf3, 0xba, 0xa7 }} + +class nsMapiSupport : public nsIMapiSupport, + public nsIObserver +{ + public : + nsMapiSupport(); + ~nsMapiSupport(); + + // Declare all interface methods we must implement. + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + NS_DECL_NSIMAPISUPPORT + + private : + + DWORD m_dwRegister; + CMapiFactory *m_nsMapiFactory; +}; + +#endif // MSG_MAPI_SUPPORT_H_ diff --git a/mailnews/mapi/mapihook/src/nsMapiRegistry.cpp b/mailnews/mapi/mapihook/src/nsMapiRegistry.cpp new file mode 100644 index 00000000000..efdfef8ff59 --- /dev/null +++ b/mailnews/mapi/mapihook/src/nsMapiRegistry.cpp @@ -0,0 +1,168 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIServiceManager.h" +#include "nsXPIDLString.h" +#include "nsIPromptService.h" +#include "nsIProxyObjectManager.h" +#include "nsProxiedService.h" + +#include "nsMapiRegistryUtils.h" +#include "nsMapiRegistry.h" + +static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + +/** Implementation of the nsIMapiRegistry interface. + * Use standard implementation of nsISupports stuff. + */ +NS_IMPL_ISUPPORTS1(nsMapiRegistry, nsIMapiRegistry); + +nsMapiRegistry::nsMapiRegistry() { + NS_INIT_ISUPPORTS(); + m_ShowDialog = ! m_registryUtils.verifyRestrictedAccess(); + m_DefaultMailClient = m_registryUtils.IsDefaultMailClient(); +} + +nsMapiRegistry::~nsMapiRegistry() { +} + +NS_IMETHODIMP +nsMapiRegistry::GetIsDefaultMailClient(PRBool * retval) { + // we need to get the value from registry everytime + // because the registry settings can be changed from + // other mail applications. + *retval = m_registryUtils.IsDefaultMailClient(); + return NS_OK; +} + +NS_IMETHODIMP +nsMapiRegistry::GetShowDialog(PRBool * retval) { + *retval = m_ShowDialog; + return NS_OK; +} + + +NS_IMETHODIMP +nsMapiRegistry::SetIsDefaultMailClient(PRBool aIsDefaultMailClient) +{ + nsresult rv = NS_OK ; + + if (aIsDefaultMailClient) + { + rv = m_registryUtils.setDefaultMailClient(); + if (NS_SUCCEEDED(rv)) + m_DefaultMailClient = PR_TRUE; + else + m_registryUtils.ShowMapiErrorDialog(); + } + else + { + rv = m_registryUtils.unsetDefaultMailClient(); + if (NS_SUCCEEDED(rv)) + m_DefaultMailClient = PR_FALSE; + else + m_registryUtils.ShowMapiErrorDialog(); + } + + return rv ; +} + +/** This will bring up the dialog box only once per session and + * only if the current app is not default Mail Client. + * This also checks the registry if the registry key + * showMapiDialog is set + */ +NS_IMETHODIMP +nsMapiRegistry::ShowMailIntegrationDialog(nsIDOMWindow *aParentWindow) { + nsresult rv; + if (!m_ShowDialog || !m_registryUtils.getShowDialog()) return NS_OK; + nsCOMPtr promptService(do_GetService( + "@mozilla.org/embedcomp/prompt-service;1", &rv)); + if (NS_SUCCEEDED(rv) && promptService) + { + nsCOMPtr bundle; + rv = m_registryUtils.MakeMapiStringBundle (getter_AddRefs (bundle)) ; + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString dialogTitle; + const PRUnichar *brandStrings[] = { m_registryUtils.brandName() }; + NS_NAMED_LITERAL_STRING(dialogTitlePropertyTag, "dialogTitle"); + rv = bundle->FormatStringFromName(dialogTitlePropertyTag.get(), + brandStrings, 1, + getter_Copies(dialogTitle)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString dialogText; + NS_NAMED_LITERAL_STRING(dialogTextPropertyTag, "dialogText"); + rv = bundle->FormatStringFromName(dialogTextPropertyTag.get(), + brandStrings, 1, + getter_Copies(dialogText)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString checkboxText; + rv = bundle->GetStringFromName( + NS_LITERAL_STRING("checkboxText").get(), + getter_Copies(checkboxText)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + PRBool checkValue = PR_FALSE; + PRInt32 buttonPressed = 0; + rv = promptService->ConfirmEx(aParentWindow, + dialogTitle, + dialogText.get(), + (nsIPromptService::BUTTON_TITLE_YES * + nsIPromptService::BUTTON_POS_0) + + (nsIPromptService::BUTTON_TITLE_NO * + nsIPromptService::BUTTON_POS_1), + nsnull, + nsnull, + nsnull, + checkboxText, + &checkValue, + &buttonPressed); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + rv = m_registryUtils.SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop", + "showMapiDialog", (checkValue) ? "0" : "1"); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + m_ShowDialog = PR_FALSE; + if (!buttonPressed) + rv = SetIsDefaultMailClient(PR_TRUE) ; // SetDefaultMailClient(); + } + return rv; +} + diff --git a/mailnews/mapi/mapihook/src/nsMapiRegistry.h b/mailnews/mapi/mapihook/src/nsMapiRegistry.h new file mode 100644 index 00000000000..294acf26a46 --- /dev/null +++ b/mailnews/mapi/mapihook/src/nsMapiRegistry.h @@ -0,0 +1,76 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsmapiregistry_h____ +#define nsmapiregistry_h____ + +#include "nsIMapiRegistry.h" + +#ifndef MAX_BUF +#define MAX_BUF 4096 +#endif + +/* c5be14ba-4e0a-4eec-a1b8-04363761d63c */ +#define NS_IMAPIREGISTRY_CID \ + { 0xc5be14ba, 0x4e0a, 0x4eec, {0xa1, 0xb8, 0x04, 0x36, 0x37, 0x61, 0xd6, 0x3c} } +#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1" +#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry" + +#define MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT "mailnews.default_mail_client" + +class nsMapiRegistry : public nsIMapiRegistry { +public: + // ctor/dtor + nsMapiRegistry(); + virtual ~nsMapiRegistry(); + + // Declare all interface methods we must implement. + NS_DECL_ISUPPORTS + NS_DECL_NSIMAPIREGISTRY + +protected: + + PRBool m_DefaultMailClient; + PRBool m_ShowDialog; + nsMapiRegistryUtils m_registryUtils ; + +private: + // Special member to handle initialization. + PRBool mHaveBeenSet; +}; // nsMapiRegistry + +#endif // nsmapiregistry_h____ diff --git a/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.cpp b/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.cpp new file mode 100644 index 00000000000..7bebd99c1d6 --- /dev/null +++ b/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.cpp @@ -0,0 +1,743 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#undef UNICODE +#undef _UNICODE + +#include "nsIServiceManager.h" +#include "msgMapiImp.h" +#include "msgMapiMain.h" +#include "nsMapiRegistryUtils.h" +#include "nsString.h" +#include "nsIStringBundle.h" +#include "nsIPromptService.h" +#include "nsXPIDLString.h" +#include "nsSpecialSystemDirectory.h" +#include "nsDirectoryService.h" +#include "nsDirectoryServiceDefs.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsIPref.h" + +static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + +#define EXE_EXTENSION ".exe" +#define USERAGENT_VERSION_PREF "general.useragent.misc" +#define USERAGENT_VERSION_NS_PREF "general.useragent.vendorSub" +#define USERAGENT_PREF_PREFIX "rv:" + +nsMapiRegistryUtils::nsMapiRegistryUtils() +{ + m_mapiStringBundle = nsnull ; +} + +const char * nsMapiRegistryUtils::thisApplication() +{ + if (m_thisApp.IsEmpty()) { + char buffer[MAX_PATH] = {0}; + DWORD len = ::GetModuleFileName(NULL, buffer, MAX_PATH); + if (!len) return nsnull ; + char shortPathBuf[MAX_PATH] = {0}; + len = ::GetShortPathName(buffer, shortPathBuf, MAX_PATH); + if (!len) return nsnull ; + m_thisApp = buffer; + m_thisApp.ToUpperCase(); + } + + return m_thisApp.get() ; +} + +const PRUnichar * nsMapiRegistryUtils::brandName() +{ + nsresult rv; + if (m_brand.IsEmpty()) { + nsCOMPtr bundleService(do_GetService( + kStringBundleServiceCID, &rv)); + if (NS_SUCCEEDED(rv) && bundleService) { + nsCOMPtr brandBundle; + rv = bundleService->CreateBundle( + "chrome://global/locale/brand.properties", + getter_AddRefs(brandBundle)); + if (NS_SUCCEEDED(rv)) { + nsXPIDLString brandName; + rv = brandBundle->GetStringFromName( + NS_LITERAL_STRING("brandShortName").get(), + getter_Copies(brandName)); + if (NS_SUCCEEDED(rv)) { + m_brand = brandName ; + } + } + } + } + + return m_brand.get() ; +} + +const PRUnichar * nsMapiRegistryUtils::versionNo() +{ + if (!m_versionNo.IsEmpty()) + return m_versionNo.get() ; + + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID); + if (prefs) { + nsXPIDLCString versionStr ; + nsresult rv = prefs->GetCharPref(USERAGENT_VERSION_NS_PREF, getter_Copies(versionStr)); + if (NS_SUCCEEDED(rv) && versionStr) + m_versionNo.AssignWithConversion (versionStr.get()) ; + else { + rv = prefs->GetCharPref(USERAGENT_VERSION_PREF, getter_Copies(versionStr)); + if (NS_SUCCEEDED(rv) && versionStr) { + m_versionNo.AssignWithConversion (versionStr.get()) ; + m_versionNo.StripChars (USERAGENT_PREF_PREFIX) ; + } + } + } + + return m_versionNo.get() ; +} + + +PRBool nsMapiRegistryUtils::verifyRestrictedAccess() { + char subKey[] = "Software\\Mozilla - Test Key"; + PRBool result = PR_FALSE; + DWORD dwDisp = 0; + HKEY key; + // Try to create/open a subkey under HKLM. + DWORD rc = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, + subKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &key, + &dwDisp); + + if (rc == ERROR_SUCCESS) { + // Key was opened; first close it. + ::RegCloseKey(key); + // Delete it if we just created it. + switch(dwDisp) { + case REG_CREATED_NEW_KEY: + ::RegDeleteKey(HKEY_LOCAL_MACHINE, subKey); + break; + case REG_OPENED_EXISTING_KEY: + break; + } + } else { + // Can't create/open it; we don't have access. + result = PR_TRUE; + } + return result; +} + +nsresult nsMapiRegistryUtils::SetRegistryKey(HKEY baseKey, const char * keyName, + const char * valueName, char * value) +{ + nsresult result = NS_ERROR_FAILURE; + HKEY key; + LONG rc = ::RegCreateKey(baseKey, keyName, &key); + + if (rc == ERROR_SUCCESS) { + rc = ::RegSetValueEx(key, valueName, NULL, REG_SZ, + (LPBYTE)(const char*)value, strlen(value)); + if (rc == ERROR_SUCCESS) { + result = NS_OK; + } + ::RegCloseKey(key); + } + return result; +} + +nsresult nsMapiRegistryUtils::DeleteRegistryValue(HKEY baseKey, const char * keyName, + const char * valueName) +{ + nsresult result = NS_ERROR_FAILURE; + HKEY key; + LONG rc = ::RegOpenKey(baseKey, keyName, &key); + + if (rc == ERROR_SUCCESS) { + rc = ::RegDeleteValue(key, valueName); + if (rc == ERROR_SUCCESS) + result = NS_OK; + ::RegCloseKey(key); + } + return result; +} + +void nsMapiRegistryUtils::GetRegistryKey(HKEY baseKey, const char * keyName, + const char * valueName, nsCAutoString & value) +{ + HKEY key; + LONG rc = ::RegOpenKey(baseKey, keyName, &key); + if (rc == ERROR_SUCCESS) { + char buffer[MAX_PATH] = {0}; + DWORD len = sizeof buffer; + rc = ::RegQueryValueEx(key, valueName, NULL, NULL, + (LPBYTE)buffer, &len); + if (rc == ERROR_SUCCESS) { + if (len) + value = buffer; + } + ::RegCloseKey(key); + } +} + + + +PRBool nsMapiRegistryUtils::IsDefaultMailClient() +{ + if (!isSmartDll() && !isMozDll()) + return PR_FALSE; + nsCAutoString name; + GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", name); + if (!name.IsEmpty()) { + nsCAutoString keyName("Software\\Clients\\Mail\\"); + keyName += name.get(); + keyName += "\\protocols\\mailto\\shell\\open\\command"; + + nsCAutoString result; + GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", result); + if (!result.IsEmpty()) { + nsCAutoString strExtension; + strExtension.Assign(EXE_EXTENSION); + result.ToUpperCase(); + strExtension.ToUpperCase(); + PRInt32 index = result.RFind(strExtension.get()); + if (index != kNotFound) { + result.Truncate(index + strExtension.Length()); + } + nsCAutoString thisApp (thisApplication()) ; + return (result == thisApp); + } + } + return PR_FALSE; + +} + +nsresult nsMapiRegistryUtils::saveDefaultMailClient() +{ + nsresult rv; + nsCAutoString name ; + GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Clients\\Mail", "", name); + if (!name.IsEmpty()) { + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", + (char *)name.get()); + if (NS_SUCCEEDED(rv)) { + nsCAutoString keyName("Software\\Clients\\Mail\\"); + keyName += name.get(); + keyName += "\\protocols\\mailto\\shell\\open\\command"; + nsCAutoString appPath ; + GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", appPath); + if (!appPath.IsEmpty()) { + nsCAutoString stringName("HKEY_LOCAL_MACHINE\\"); + stringName += keyName.get(); + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + stringName.get(), (char *)appPath.get()); + } + } + } + else + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", + ""); + return rv; +} + +nsresult nsMapiRegistryUtils::saveUserDefaultMailClient() +{ + nsresult rv; + nsCAutoString name ; + GetRegistryKey(HKEY_CURRENT_USER,"Software\\Clients\\Mail", "", name); + if (!name.IsEmpty()) { + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "HKEY_CURRENT_USER\\Software\\Clients\\Mail", + (char *)name.get()); + } + else { + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "HKEY_CURRENT_USER\\Software\\Clients\\Mail", + ""); + } + return rv; +} + +/** + * Check whether it is a smart dll or not. Smart dll is the one installed by + * IE5 or Outlook Express which forwards the MAPI calls to the dll based on the + * registry key setttings. + * Returns TRUE if is a smart dll. + */ + +typedef HRESULT (FAR PASCAL GetOutlookVersionFunc)(); +PRBool nsMapiRegistryUtils::isSmartDll() +{ + char buffer[MAX_PATH] = {0}; + if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) + return PR_FALSE; + PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll"); + + HINSTANCE hInst; + GetOutlookVersionFunc *doesExist = nsnull; + hInst = LoadLibrary(buffer); + if (hInst == nsnull) + return PR_FALSE; + + doesExist = (GetOutlookVersionFunc *) GetProcAddress (hInst, "GetOutlookVersion"); + FreeLibrary(hInst); + + return (doesExist != nsnull); +} + +typedef HRESULT (FAR PASCAL GetMapiDllVersion)(); +/** + * Checks whether mapi32.dll is installed by this app. + * Returns TRUE if it is. + */ +PRBool nsMapiRegistryUtils::isMozDll() +{ + char buffer[MAX_PATH] = {0}; + if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) + return PR_FALSE; + PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll"); + + HINSTANCE hInst; + GetMapiDllVersion *doesExist = nsnull; + hInst = LoadLibrary(buffer); + if (hInst == nsnull) + return PR_FALSE; + + doesExist = (GetMapiDllVersion *) GetProcAddress (hInst, "GetMapiDllVersion"); + FreeLibrary(hInst); + + return (doesExist != nsnull); +} + +/** Renames Mapi32.dl in system directory to Mapi32_moz_bak.dll + * copies the mozMapi32.dll from bin directory to the system directory + */ +nsresult nsMapiRegistryUtils::CopyMozMapiToWinSysDir() +{ + nsresult rv; + char buffer[MAX_PATH] = {0}; + if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) + return NS_ERROR_FAILURE; + + nsCAutoString filePath(buffer); + filePath.Append("\\Mapi32_moz_bak.dll"); + + nsCOMPtr pCurrentMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv); + if (NS_FAILED(rv) || !pCurrentMapiFile) return rv; + pCurrentMapiFile->InitWithPath(filePath.get()); + + nsCOMPtr pMozMapiFile; + nsCOMPtr directoryService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (!directoryService) return NS_ERROR_FAILURE; + rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), + getter_AddRefs(pMozMapiFile)); + + if (NS_FAILED(rv)) return rv; + pMozMapiFile->Append("mozMapi32.dll"); + + PRBool bExist; + rv = pMozMapiFile->Exists(&bExist); + if (NS_FAILED(rv) || !bExist) return rv; + + rv = pCurrentMapiFile->Exists(&bExist); + if (NS_SUCCEEDED(rv) && bExist) + { + rv = pCurrentMapiFile->Remove(PR_FALSE); + } + if (NS_FAILED(rv)) return rv; + filePath.Assign(buffer); + filePath.Append("\\Mapi32.dll"); + pCurrentMapiFile->InitWithPath(filePath.get()); + rv = pCurrentMapiFile->Exists(&bExist); + if (NS_SUCCEEDED(rv) && bExist) + { + rv = pCurrentMapiFile->MoveTo(nsnull, "Mapi32_moz_bak.dll"); + if (NS_FAILED(rv)) return rv; + nsCAutoString fullFilePath(buffer); + fullFilePath.Append("\\Mapi32_moz_bak.dll"); + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "Mapi_backup_dll", + (char *)fullFilePath.get()); + if (NS_FAILED(rv)) { + RestoreBackedUpMapiDll(); + return rv; + } + } + + NS_NAMED_LITERAL_STRING(fileName, "Mapi32.dll"); + filePath.Assign(buffer); + pCurrentMapiFile->InitWithPath(filePath.get()); + rv = pMozMapiFile->CopyToUnicode(pCurrentMapiFile, fileName.get()); + if (NS_FAILED(rv)) + RestoreBackedUpMapiDll(); + return rv; +} + +/** deletes the Mapi32.dll in system directory and renames Mapi32_moz_bak.dll + * to Mapi32.dll + */ +nsresult nsMapiRegistryUtils::RestoreBackedUpMapiDll() +{ + nsresult rv; + char buffer[MAX_PATH] = {0}; + if (GetSystemDirectory(buffer, sizeof(buffer)) == 0) + return NS_ERROR_FAILURE; + + nsCAutoString filePath(buffer); + nsCAutoString previousFileName(buffer); + filePath.Append("\\Mapi32.dll"); + previousFileName.Append("\\Mapi32_moz_bak.dll"); + + nsCOMPtr pCurrentMapiFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); + if (NS_FAILED(rv) || !pCurrentMapiFile) return NS_ERROR_FAILURE; + pCurrentMapiFile->InitWithPath(filePath.get()); + + nsCOMPtr pPreviousMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv); + if (NS_FAILED(rv) || !pPreviousMapiFile) return NS_ERROR_FAILURE; + pPreviousMapiFile->InitWithPath(previousFileName.get()); + + PRBool bExist; + rv = pCurrentMapiFile->Exists(&bExist); + if (NS_SUCCEEDED(rv) && bExist) { + rv = pCurrentMapiFile->Remove(PR_FALSE); + if (NS_FAILED(rv)) return rv; + } + + rv = pPreviousMapiFile->Exists(&bExist); + if (NS_SUCCEEDED(rv) && bExist) + rv = pPreviousMapiFile->MoveTo(nsnull, "Mapi32.dll"); + if (NS_SUCCEEDED(rv)) + DeleteRegistryValue(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "Mapi_backup_dll"); + return rv; +} + +/** Sets Mozilla as default Mail Client + */ +nsresult nsMapiRegistryUtils::setDefaultMailClient() +{ + nsresult rv; + nsresult mailKeySet=NS_ERROR_FAILURE; + if (verifyRestrictedAccess()) return NS_ERROR_FAILURE; + if (!isSmartDll()) { + if (NS_FAILED(CopyMozMapiToWinSysDir())) return NS_ERROR_FAILURE; + } + rv = saveDefaultMailClient(); + if (NS_FAILED(saveUserDefaultMailClient()) || + NS_FAILED(rv)) return NS_ERROR_FAILURE; + nsCAutoString keyName("Software\\Clients\\Mail\\"); + + nsCAutoString appName (NS_ConvertUCS2toUTF8(brandName()).get()); + if (!appName.IsEmpty()) { + keyName.Append(appName.get()); + + nsCOMPtr bundle; + rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ; + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString defaultMailTitle; + const PRUnichar *keyValuePrefixStr[] = { brandName(), versionNo() }; + NS_NAMED_LITERAL_STRING(defaultMailTitleTag, "defaultMailDisplayTitle"); + rv = bundle->FormatStringFromName(defaultMailTitleTag.get(), + keyValuePrefixStr, 2, + getter_Copies(defaultMailTitle)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), + "", NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(defaultMailTitle).get()) ) ; + } + else + rv = NS_ERROR_FAILURE; + if (NS_SUCCEEDED(rv)) { + nsCAutoString thisApp (thisApplication()) ; + if (NS_FAILED(rv)) return rv ; + + nsCAutoString dllPath (thisApp) ; + PRInt32 index = dllPath.RFind("\\"); + if (index != kNotFound) + dllPath.Truncate(index + 1); + dllPath += "mozMapi32.dll"; + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), "DLLPath", + (char *)dllPath.get()); + if (NS_SUCCEEDED(rv)) { + keyName.Append("\\protocols\\mailto"); + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), + "", "URL:MailTo Protocol"); + if (NS_SUCCEEDED(rv)) { + nsCAutoString appPath (thisApp); + appPath += " \"%1\""; + keyName.Append("\\shell\\open\\command"); + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), + "", (char *)appPath.get()); + if (NS_SUCCEEDED(rv)) { + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Clients\\Mail", + "", (char *)appName.get()); + } + if (NS_SUCCEEDED(rv)) { + nsCAutoString mailAppPath(thisApp); + mailAppPath += " -mail"; + nsCAutoString appKeyName ("Software\\Clients\\Mail\\"); + appKeyName.Append(appName.get()); + appKeyName.Append("\\shell\\open\\command"); + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + appKeyName.get(), + "", (char *)mailAppPath.get()); + } + if (NS_SUCCEEDED(rv)) { + nsCAutoString iconPath(thisApp); + iconPath += ",0"; + nsCAutoString iconKeyName ("Software\\Clients\\Mail\\"); + iconKeyName.Append(appName.get()); + iconKeyName.Append("\\DefaultIcon"); + mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, + iconKeyName.get(), + "", (char *)iconPath.get()); + } + } + } + } + + if (NS_SUCCEEDED(mailKeySet)) { + nsresult desktopKeySet = SetRegistryKey(HKEY_CURRENT_USER, + "Software\\Clients\\Mail", + "", (char *)appName.get()); + if (NS_SUCCEEDED(desktopKeySet)) { + desktopKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "defaultMailHasBeenSet", "1"); + } + ::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, + (LPARAM)"Software\\Clients\\Mail"); + RegisterServer(CLSID_CMapiImp, "Mozilla MAPI", "mozMapi", "mozMapi.1"); + return desktopKeySet; + } + + return mailKeySet; +} + +/** Removes Mozilla as the default Mail client and restores the previous setting + */ +nsresult nsMapiRegistryUtils::unsetDefaultMailClient() { + nsresult result = NS_OK; + nsresult mailKeySet = NS_ERROR_FAILURE; + if (verifyRestrictedAccess()) return NS_ERROR_FAILURE; + if (!isSmartDll()) { + if (NS_FAILED(RestoreBackedUpMapiDll())) return NS_ERROR_FAILURE; + } + nsCAutoString name ; + GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop", + "HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", name); + nsCAutoString appName (NS_ConvertUCS2toUTF8(brandName()).get()); + + if (!name.IsEmpty() && !appName.IsEmpty() && name.Equals(appName)) { + nsCAutoString keyName("HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail\\"); + keyName.Append(appName.get()); + keyName.Append("\\protocols\\mailto\\shell\\open\\command"); + nsCAutoString appPath ; + GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop", + keyName.get(), appPath); + if (!appPath.IsEmpty()) { + keyName.Assign("Software\\Clients\\Mail\\"); + keyName.Append(appName.get()); + keyName.Append("\\protocols\\mailto\\shell\\open\\command"); + result = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), + "", (char *)appPath.get()); + if (NS_SUCCEEDED(result)) { + PRInt32 index = appPath.RFind("\\"); + if (index != kNotFound) + appPath.Truncate(index + 1); + appPath += "mozMapi32.dll"; + keyName.Assign("Software\\Clients\\Mail\\"); + keyName.Append(appName.get()); + result = SetRegistryKey(HKEY_LOCAL_MACHINE, + keyName.get(), + "DLLPath", (char *) appPath.get()); + } + } + } + if (!name.IsEmpty()) { + if (NS_SUCCEEDED(result)) { + mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Clients\\Mail", + "", (char *)name.get()); + } + } + else + mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Clients\\Mail", + "", ""); + + if (NS_SUCCEEDED(mailKeySet)) { + nsCAutoString userAppName ; + GetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "HKEY_CURRENT_USER\\Software\\Clients\\Mail", userAppName); + nsresult desktopKeySet = NS_OK; + if (!userAppName.IsEmpty()) { + desktopKeySet = SetRegistryKey(HKEY_CURRENT_USER, + "Software\\Clients\\Mail", + "", (char *)userAppName.get()); + } + else { + DeleteRegistryValue(HKEY_CURRENT_USER, "Software\\Clients\\Mail", ""); + } + if (NS_SUCCEEDED(desktopKeySet)) { + desktopKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "defaultMailHasBeenSet", "0"); + } + ::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, + (LPARAM)"Software\\Clients\\Mail"); + UnregisterServer(CLSID_CMapiImp, "mozMapi", "mozMapi.1"); + return desktopKeySet; + } + return mailKeySet; +} + +/** Returns FALSE if showMapiDialog is set to 0. + * Returns TRUE otherwise + * Also returns TRUE if the Mozilla has been set as the default mail client + * and some other application has changed that setting. + * This function gets called only if the current app is not the default mail + * client + */ +PRBool nsMapiRegistryUtils::getShowDialog() { + PRBool rv = PR_FALSE; + nsCAutoString showDialog ; + GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop", + "showMapiDialog", showDialog); + // if the user has not selected the checkbox, show dialog + if (showDialog.IsEmpty() || showDialog.Equals("1")) + rv = PR_TRUE; + + if (!rv) { + // even if the user has selected the checkbox + // show it if some other application has changed the + // default setting. + nsCAutoString setMailDefault ; + GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Mozilla\\Desktop", + "defaultMailHasBeenSet", setMailDefault); + if (setMailDefault.Equals("1")) { + // need to reset the defaultMailHasBeenSet to "0" + // so that after the dialog is displayed once, + // we do not keep displaying this dialog after the user has + // selected the checkbox + rv = SetRegistryKey(HKEY_LOCAL_MACHINE, + "Software\\Mozilla\\Desktop", + "defaultMailHasBeenSet", "0"); + rv = PR_TRUE; + } + } + return rv; +} + +nsresult nsMapiRegistryUtils::MakeMapiStringBundle(nsIStringBundle ** aMapiStringBundle) +{ + nsresult rv = NS_OK ; + + if (m_mapiStringBundle) + { + *aMapiStringBundle = m_mapiStringBundle ; + NS_ADDREF(*aMapiStringBundle); + return rv ; + } + + nsCOMPtr bundleService(do_GetService( + kStringBundleServiceCID, &rv)); + if (NS_FAILED(rv) || !bundleService) return NS_ERROR_FAILURE; + + rv = bundleService->CreateBundle( + MAPI_PROPERTIES_CHROME, + getter_AddRefs(m_mapiStringBundle)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + NS_ADDREF(*aMapiStringBundle = m_mapiStringBundle) ; + + return rv ; +} + +nsresult nsMapiRegistryUtils::ShowMapiErrorDialog() +{ + nsresult rv; + nsCOMPtr promptService(do_GetService( + "@mozilla.org/embedcomp/prompt-service;1", &rv)); + if (NS_SUCCEEDED(rv) && promptService) + { + nsCOMPtr bundle; + rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ; + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString dialogTitle; + const PRUnichar *brandStrings[] = { brandName() }; + NS_NAMED_LITERAL_STRING(dialogTitlePropertyTag, "errorMessageTitle"); + rv = bundle->FormatStringFromName(dialogTitlePropertyTag.get(), + brandStrings, 1, + getter_Copies(dialogTitle)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString dialogText; + NS_NAMED_LITERAL_STRING(dialogTextPropertyTag, "errorMessage"); + rv = bundle->FormatStringFromName(dialogTextPropertyTag.get(), + brandStrings, 1, + getter_Copies(dialogText)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + rv = promptService->Alert(nsnull, dialogTitle, + dialogText); + } + return rv; +} + diff --git a/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.h b/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.h new file mode 100644 index 00000000000..2c19dd7703a --- /dev/null +++ b/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.h @@ -0,0 +1,112 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Srilatha Moturi + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsmapiregistryutils_h____ +#define nsmapiregistryutils_h____ + +#include +#include +#include + +#include "Registry.h" +#include "nsString.h" +#include "nsIStringBundle.h" + +class nsMapiRegistryUtils +{ +private : + nsCAutoString m_thisApp ; + nsAutoString m_brand ; + nsAutoString m_versionNo ; + + nsCOMPtr m_mapiStringBundle ; +public : + nsMapiRegistryUtils() ; + + // returns TRUE if the Mapi32.dll is smart dll. + PRBool isSmartDll(); + // returns TRUE if the Mapi32.dll is a Mozilla dll. + PRBool isMozDll(); + + // Returns the (fully-qualified) name of this executable. + const char * thisApplication() ; + // This returns the brand name for this application + const PRUnichar * brandName() ; + // This returns the version no for this application + const PRUnichar * versionNo() ; + // verifyRestrictedAccess - Returns PR_TRUE if this user only has restricted access + // to the registry keys we need to modify. + PRBool verifyRestrictedAccess() ; + + // set the Windows registry key +nsresult SetRegistryKey(HKEY baseKey, const char * keyName, + const char * valueName, char * value); + // delete a registry key +nsresult DeleteRegistryValue(HKEY baseKey, const char * keyName, + const char * valueName); + // get a Windows registry key + void GetRegistryKey(HKEY baseKey, const char * keyName, + const char * valueName, nsCAutoString & value) ; + + // Returns TRUE if the current application is default mail client. +PRBool IsDefaultMailClient(); + // Sets Mozilla as default Mail Client + nsresult setDefaultMailClient() ; + // Removes Mozilla as the default Mail client and restores the previous setting + nsresult unsetDefaultMailClient() ; + + // Saves the current setting of the default Mail Client in + // HKEY_LOCAL_MACHINE\\Software\\Mozilla\\Desktop +nsresult saveDefaultMailClient(); + // Saves the current user setting of the default Mail Client in + // HKEY_LOCAL_MACHINE\\Software\\Mozilla\\Desktop +nsresult saveUserDefaultMailClient(); + +nsresult CopyMozMapiToWinSysDir(); +nsresult RestoreBackedUpMapiDll(); + + // Returns FALSE if showMapiDialog is set to 0. + PRBool getShowDialog() ; + + // create a string bundle for MAPI messages + nsresult MakeMapiStringBundle(nsIStringBundle ** aMapiStringBundle) ; + // display an error dialog for MAPI messages + nsresult ShowMapiErrorDialog() ; + +} ; + +#endif