Skip to content

Commit b990612

Browse files
Load MAPI When Outlook.exe isn't Present (#883)
* Consume mapistub olmap32 load changes * remove unused var * update mapistub * formatting * fix formatting
1 parent 54be86a commit b990612

File tree

9 files changed

+90
-8
lines changed

9 files changed

+90
-8
lines changed

UI/Dialogs/Editors/Options.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ namespace dialog::editor
117117
COptions MyOptions(lpParentWnd);
118118
MyOptions.DoModal();
119119

120-
mapistub::ForceOutlookMAPI(registry::forceOutlookMAPI);
121-
mapistub::ForceSystemMAPI(registry::forceSystemMAPI);
120+
registry::PushOptionsToStub();
122121
return MyOptions.NeedPropRefresh();
123122
}
124123
} // namespace dialog::editor

UI/ParentWnd.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ namespace ui
7676
m_hwinEventHook = SetWinEventHook(
7777
EVENT_OBJECT_REORDER, EVENT_OBJECT_REORDER, nullptr, &MyWinEventProc, GetCurrentProcessId(), NULL, NULL);
7878

79-
mapistub::ForceOutlookMAPI(registry::forceOutlookMAPI);
80-
mapistub::ForceSystemMAPI(registry::forceSystemMAPI);
79+
registry::PushOptionsToStub();
8180

8281
addin::LoadAddIns();
8382

core/mapi/version.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace version
1717
for (const auto component : mapistub::g_pszOutlookQualifiedComponents)
1818
{
1919
auto b64 = false;
20-
auto lpszTempPath = mapistub::GetOutlookPath(component, &b64);
20+
auto lpszTempPath = mapistub::GetOLMAPI32Path(component);
2121

2222
if (!lpszTempPath.empty())
2323
{
@@ -34,6 +34,8 @@ namespace version
3434
{
3535
szOut = strings::formatmessage(
3636
IDS_OUTLOOKVERSIONSTRING, lpszTempPath.c_str(), lpszTempVer.c_str(), lpszTempLang.c_str());
37+
b64 = Is64BitModule(lpszTempPath);
38+
3739
szOut += strings::formatmessage(b64 ? IDS_TRUE : IDS_FALSE);
3840
szOut += L"\n"; // STRING_OK
3941
}
@@ -194,4 +196,71 @@ namespace version
194196

195197
return szVersionString;
196198
}
199+
200+
bool Is64BitModule(const std::wstring& modulePath)
201+
{
202+
if (modulePath.empty()) return false;
203+
204+
const auto hFile = CreateFileW(
205+
modulePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
206+
207+
if (hFile == INVALID_HANDLE_VALUE)
208+
{
209+
output::DebugPrint(
210+
output::dbgLevel::Generic, L"Is64BitModule: Failed to open file %ws\n", modulePath.c_str());
211+
return false;
212+
}
213+
214+
// Read DOS header
215+
IMAGE_DOS_HEADER dosHeader = {};
216+
DWORD bytesRead = 0;
217+
if (!ReadFile(hFile, &dosHeader, sizeof(dosHeader), &bytesRead, nullptr) || bytesRead != sizeof(dosHeader) ||
218+
dosHeader.e_magic != IMAGE_DOS_SIGNATURE)
219+
{
220+
CloseHandle(hFile);
221+
return false;
222+
}
223+
224+
// Seek to PE header
225+
if (SetFilePointer(hFile, dosHeader.e_lfanew, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
226+
{
227+
CloseHandle(hFile);
228+
return false;
229+
}
230+
231+
// Read PE signature
232+
DWORD peSignature = 0;
233+
if (!ReadFile(hFile, &peSignature, sizeof(peSignature), &bytesRead, nullptr) ||
234+
bytesRead != sizeof(peSignature) || peSignature != IMAGE_NT_SIGNATURE)
235+
{
236+
CloseHandle(hFile);
237+
return false;
238+
}
239+
240+
// Read file header to get machine type
241+
IMAGE_FILE_HEADER fileHeader = {};
242+
if (!ReadFile(hFile, &fileHeader, sizeof(fileHeader), &bytesRead, nullptr) || bytesRead != sizeof(fileHeader))
243+
{
244+
CloseHandle(hFile);
245+
return false;
246+
}
247+
248+
CloseHandle(hFile);
249+
250+
// Check machine type to determine if it's 64-bit
251+
switch (fileHeader.Machine)
252+
{
253+
case IMAGE_FILE_MACHINE_AMD64:
254+
case IMAGE_FILE_MACHINE_IA64:
255+
case IMAGE_FILE_MACHINE_ARM64:
256+
return true;
257+
case IMAGE_FILE_MACHINE_I386:
258+
case IMAGE_FILE_MACHINE_ARM:
259+
case IMAGE_FILE_MACHINE_ARMNT:
260+
return false;
261+
default:
262+
// Unknown architecture, assume 32-bit
263+
return false;
264+
}
265+
}
197266
} // namespace version

core/mapi/version.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
namespace version
44
{
55
std::wstring GetOutlookVersionString();
6+
bool Is64BitModule(const std::wstring& modulePath);
67
} // namespace version

core/res/MFCMapi.rc2

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ Set ulEventMask"
341341
IDS_COMPUTESTOREHASH "Compute Store Hash"
342342
IDS_COMPUTESTOREHASHPROMPT "Enter store entry ID and file name"
343343
IDS_OUTLOOKVERSIONTITLE "Outlook Version"
344-
IDS_OUTLOOKVERSIONPROMPT "Outlook path, version and language obtained through MsiProvideQualifiedComponent and MsiGetFileVersion:"
344+
IDS_OUTLOOKVERSIONPROMPT "OLMAPI32 path, version and language obtained through MsiProvideQualifiedComponent and MsiGetFileVersion:"
345345
IDS_OUTLOOKVERSIONSTRING "Path: %1!ws!\nVersion: %2!ws!\nLang: %3!ws!\n64 bit: "
346346
IDS_NOOUTLOOK "Outlook does not appear to be installed on this machine."
347347

@@ -993,6 +993,7 @@ IDS_REGKEY_HEAPENABLETERMINATIONONCORRUPTION "Terminate on heap corruption (requ
993993
IDS_REGKEY_LOADADDINS "Load add-ins (requires restart)"
994994
IDS_REGKEY_FORCEOUTLOOKMAPI "Force the use of Outlook's MAPI files"
995995
IDS_REGKEY_FORCESYSTEMMAPI "Force the use of the system's MAPI files"
996+
IDS_REGKEY_PREFER_OLMAPI32 "Prefer olmapi32.dll over other MAPI files"
996997
IDS_REGKEY_UIDIAG "Show UI diagnostics"
997998

998999
// RestrictEditor.cpp
@@ -1708,7 +1709,7 @@ IDS_EDMAPIINITIALIZEFAILED "MAPIInitialize failed with error 0x%08X == %ws.\r\n\
17081709
\r\n\
17091710
Here are some known causes for this.\r\n\
17101711
1 - A 64 bit version of Outlook is not installed. The 64 bit version of MFCMAPI only works with a 64 bit version of Outlook.\r\n\
1711-
\tSee https://github.com/microsoft/mfcmapifor the latest 32 bit bit build of MFCMAPI.\r\n\
1712+
\tSee https://github.com/microsoft/mfcmapi for the latest 32 bit bit build of MFCMAPI.\r\n\
17121713
2 - Windows Mail is registered as the Default Mail Client.\r\n\
17131714
\tSee http://msdn.microsoft.com/en-gb/library/dd162409.aspx for information on setting the Default Mail Client."
17141715
#else

core/res/Resource.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,3 +1234,4 @@
12341234
#define IDS_RESERVED 35871
12351235
#define IDS_CAPABILITIES_FOLDER 35872
12361236
#define IDS_CAPABILITIES_RESTRICTION 35873
1237+
#define IDS_REGKEY_PREFER_OLMAPI32 35874

core/utility/registry.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <core/utility/output.h>
55
#include <core/utility/error.h>
66
#include <core/utility/import.h>
7+
#include <mapistub/library/stubutils.h>
78

89
namespace registry
910
{
@@ -63,6 +64,7 @@ namespace registry
6364
boolRegKey loadAddIns{L"LoadAddIns", true, false, IDS_REGKEY_LOADADDINS};
6465
boolRegKey forceOutlookMAPI{L"ForceOutlookMAPI", false, false, IDS_REGKEY_FORCEOUTLOOKMAPI};
6566
boolRegKey forceSystemMAPI{L"ForceSystemMAPI", false, false, IDS_REGKEY_FORCESYSTEMMAPI};
67+
boolRegKey preferOlmapi32{L"PreferOlmapi32", true, false, IDS_REGKEY_PREFER_OLMAPI32};
6668
boolRegKey uiDiag{L"UIDiag", false, false, IDS_REGKEY_UIDIAG};
6769
boolRegKey displayAboutDialog{L"DisplayAboutDialog", true, false, NULL};
6870
wstringRegKey propertyColumnOrder{L"PropertyColumnOrder", L"", false, NULL};
@@ -96,6 +98,7 @@ namespace registry
9698
&loadAddIns,
9799
&forceOutlookMAPI,
98100
&forceSystemMAPI,
101+
&preferOlmapi32,
99102
&uiDiag,
100103
&displayAboutDialog,
101104
&propertyColumnOrder,
@@ -331,4 +334,11 @@ namespace registry
331334

332335
if (hRootKey) EC_W32_S(RegCloseKey(hRootKey));
333336
}
337+
338+
void PushOptionsToStub()
339+
{
340+
mapistub::ForceOutlookMAPI(forceOutlookMAPI);
341+
mapistub::ForceSystemMAPI(forceSystemMAPI);
342+
mapistub::PreferOlmapi32(preferOlmapi32);
343+
}
334344
} // namespace registry

core/utility/registry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ namespace registry
166166
{
167167
WriteBinToRegistry(hKey, szValueName, std::vector<BYTE>(lpbin, lpbin + cb), bSecure);
168168
}
169+
void PushOptionsToStub();
169170

170171
extern dwordRegKey debugTag;
171172
extern boolRegKey debugToFile;
@@ -194,6 +195,7 @@ namespace registry
194195
extern boolRegKey loadAddIns;
195196
extern boolRegKey forceOutlookMAPI;
196197
extern boolRegKey forceSystemMAPI;
198+
extern boolRegKey preferOlmapi32;
197199
extern boolRegKey uiDiag;
198200
extern boolRegKey displayAboutDialog;
199201
extern wstringRegKey propertyColumnOrder;

0 commit comments

Comments
 (0)