From b6e5ee604ac46d4a2d1c1cc547100cbe5c36187f Mon Sep 17 00:00:00 2001 From: Owen Rudge Date: Fri, 18 Sep 2009 15:15:34 +0100 Subject: [PATCH] mapi32: Scan registry for MAPI providers and load them. --- dlls/mapi32/Makefile.in | 2 +- dlls/mapi32/mapi32_main.c | 5 +- dlls/mapi32/util.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/mapi32/util.h | 28 +++++++++ 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 dlls/mapi32/util.h diff --git a/dlls/mapi32/Makefile.in b/dlls/mapi32/Makefile.in index 3e311de00c0..e38cfcf02e8 100644 --- a/dlls/mapi32/Makefile.in +++ b/dlls/mapi32/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mapi32.dll IMPORTLIB = mapi32 -IMPORTS = uuid shlwapi shell32 kernel32 +IMPORTS = uuid shlwapi shell32 advapi32 kernel32 C_SRCS = \ imalloc.c \ diff --git a/dlls/mapi32/mapi32_main.c b/dlls/mapi32/mapi32_main.c index b9d5888bead..0f82e762369 100644 --- a/dlls/mapi32/mapi32_main.c +++ b/dlls/mapi32/mapi32_main.c @@ -1,7 +1,7 @@ /* * MAPI basics * - * Copyright 2001 CodeWeavers Inc. + * Copyright 2001, 2009 CodeWeavers Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,7 @@ #include "mapiform.h" #include "mapi.h" #include "wine/debug.h" +#include "util.h" WINE_DEFAULT_DEBUG_CHANNEL(mapi); @@ -45,9 +46,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); + load_mapi_providers(); break; case DLL_PROCESS_DETACH: TRACE("DLL_PROCESS_DETACH: %d objects remaining\n", MAPI_ObjectCount); + unload_mapi_providers(); break; } return TRUE; diff --git a/dlls/mapi32/util.c b/dlls/mapi32/util.c index c621a0f8c49..6044749991f 100644 --- a/dlls/mapi32/util.c +++ b/dlls/mapi32/util.c @@ -2,6 +2,7 @@ * MAPI Utility functions * * Copyright 2004 Jon Griffiths + * Copyright 2009 Owen Rudge for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +38,7 @@ #include "mapival.h" #include "xcmc.h" #include "msi.h" +#include "util.h" WINE_DEFAULT_DEBUG_CHANNEL(mapi); @@ -903,3 +905,145 @@ HRESULT WINAPI HrQueryAllRows(LPMAPITABLE lpTable, LPSPropTagArray lpPropTags, *lppRows = NULL; return MAPI_E_CALL_FAILED; } + +static HMODULE mapi_provider; +static HMODULE mapi_ex_provider; + +/************************************************************************** + * load_mapi_provider + * + * Attempts to load a MAPI provider from the specified registry key. + * + * Returns a handle to the loaded module in `mapi_provider' if successful. + */ +static void load_mapi_provider(HKEY hkeyMail, LPCWSTR valueName, HMODULE *mapi_provider) +{ + static const WCHAR mapi32_dll[] = {'m','a','p','i','3','2','.','d','l','l',0 }; + + DWORD dwType, dwLen = 0; + LPWSTR dllPath; + + /* Check if we have a value set for DLLPath */ + if ((RegQueryValueExW(hkeyMail, valueName, NULL, &dwType, NULL, &dwLen) == ERROR_SUCCESS) && + ((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)) && (dwLen > 0)) + { + dllPath = HeapAlloc(GetProcessHeap(), 0, dwLen); + + if (dllPath) + { + RegQueryValueExW(hkeyMail, valueName, NULL, NULL, (LPBYTE)dllPath, &dwLen); + + /* Check that this value doesn't refer to mapi32.dll (eg, as Outlook does) */ + if (lstrcmpiW(dllPath, mapi32_dll) != 0) + { + if (dwType == REG_EXPAND_SZ) + { + DWORD dwExpandLen; + LPWSTR dllPathExpanded; + + /* Expand the path if necessary */ + dwExpandLen = ExpandEnvironmentStringsW(dllPath, NULL, 0); + dllPathExpanded = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * dwExpandLen + 1); + + if (dllPathExpanded) + { + ExpandEnvironmentStringsW(dllPath, dllPathExpanded, dwExpandLen + 1); + + HeapFree(GetProcessHeap(), 0, dllPath); + dllPath = dllPathExpanded; + } + } + + /* Load the DLL */ + TRACE("loading %s\n", debugstr_w(dllPath)); + *mapi_provider = LoadLibraryW(dllPath); + } + + HeapFree(GetProcessHeap(), 0, dllPath); + } + } +} + +/************************************************************************** + * load_mapi_providers + * + * Scans the registry for MAPI providers and attempts to load a Simple and + * Extended MAPI library. + * + * Returns TRUE if at least one library loaded, FALSE otherwise. + */ +void load_mapi_providers(void) +{ + static const WCHAR regkey_mail[] = { + 'S','o','f','t','w','a','r','e','\\','C','l','i','e','n','t','s','\\', + 'M','a','i','l',0 }; + + static const WCHAR regkey_dllpath[] = {'D','L','L','P','a','t','h',0 }; + static const WCHAR regkey_dllpath_ex[] = {'D','L','L','P','a','t','h','E','x',0 }; + static const WCHAR regkey_backslash[] = { '\\', 0 }; + + HKEY hkeyMail; + DWORD dwType, dwLen = 0; + LPWSTR appName = NULL, appKey = NULL; + + TRACE("()\n"); + + /* Open the Mail key */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, regkey_mail, 0, KEY_READ, &hkeyMail) != ERROR_SUCCESS) + return; + + /* Check if we have a default value set, and the length of it */ + if ((RegQueryValueExW(hkeyMail, NULL, NULL, &dwType, NULL, &dwLen) != ERROR_SUCCESS) || + !((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)) || (dwLen == 0)) + goto cleanUp; + + appName = HeapAlloc(GetProcessHeap(), 0, dwLen); + + if (!appName) + goto cleanUp; + + /* Get the value, and get the path to the app key */ + RegQueryValueExW(hkeyMail, NULL, NULL, NULL, (LPBYTE)appName, &dwLen); + + TRACE("appName: %s\n", debugstr_w(appName)); + + appKey = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(regkey_mail) + + lstrlenW(regkey_backslash) + lstrlenW(appName))); + + if (!appKey) + goto cleanUp; + + lstrcpyW(appKey, regkey_mail); + lstrcatW(appKey, regkey_backslash); + lstrcatW(appKey, appName); + + RegCloseKey(hkeyMail); + + TRACE("appKey: %s\n", debugstr_w(appKey)); + + /* Open the app's key */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, appKey, 0, KEY_READ, &hkeyMail) != ERROR_SUCCESS) + return; + + /* Try to load the providers */ + load_mapi_provider(hkeyMail, regkey_dllpath, &mapi_provider); + load_mapi_provider(hkeyMail, regkey_dllpath_ex, &mapi_ex_provider); + +cleanUp: + RegCloseKey(hkeyMail); + HeapFree(GetProcessHeap(), 0, appKey); + HeapFree(GetProcessHeap(), 0, appName); +} + +/************************************************************************** + * unload_mapi_providers + * + * Unloads any loaded MAPI libraries. + */ +void unload_mapi_providers(void) +{ + TRACE("()\n"); + + FreeLibrary(mapi_provider); + FreeLibrary(mapi_ex_provider); +} diff --git a/dlls/mapi32/util.h b/dlls/mapi32/util.h new file mode 100644 index 00000000000..450d671c1a5 --- /dev/null +++ b/dlls/mapi32/util.h @@ -0,0 +1,28 @@ +/* + * MAPI utility header file + * + * Copyright 2009 Owen Rudge for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _MAPI_UTIL_H + +#define _MAPI_UTIL_H + +extern void load_mapi_providers(void); +extern void unload_mapi_providers(void); + +#endif -- 2.11.4.GIT